home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 1191 / 1191.xpi / chrome / reminderfox.jar / content / reminderfox / reminderFox.js < prev    next >
Text File  |  2010-01-29  |  118KB  |  3,111 lines

  1. // constants
  2. const reminderFox_TOOLTIP_LINE_LENGTH = 100;
  3. const reminderFox_TOOLTIP_WITH_TODOS_LINE_LENGTH = 65;
  4. const reminderFox_ALERT_TEXT_MAX_LENGTH = 100;
  5. const reminderFox_MONTHLY_WILDCARD = "*";
  6.  
  7. const reminderFox_HOUR_TIMEOUT = 1800000; // changed to half hour instead of 1 hour= 3600000  // dump: externalize this to a pref (read it first time only; then store it)
  8. const reminderFox_ALARM_DELAY = 4000;  // make sure 500ms between each alarm, or mozilla creates a blank window
  9.  
  10. var reminderFox_alarmList = new Array();
  11.  
  12. var reminderFox_lastStatusBarClick;
  13.  
  14.  var reminderFox_initialized = false;
  15. // Cache the last reminders
  16. var reminderFox_lastDay = null;
  17.  
  18. var reminderFox_lastAlarmTime = null;
  19.  
  20. // Launches the 'edit reminder' dialog, fills in Reminders list
  21. function reminderFox_openAddRemindersDialog( closeIfOpen ) {
  22.    var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  23.    var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  24.    var topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxEdit");
  25.    if (topWindow) {
  26.         var currentClickTime = new Date().getTime();
  27.         if ( reminderFox_lastStatusBarClick != null &&  
  28.             ( (currentClickTime - reminderFox_lastStatusBarClick ) < 700 ) ) {
  29.                 closeIfOpen = false;
  30.          }
  31.            if ( closeIfOpen != null && closeIfOpen == true ) {
  32.                topWindow.close();
  33.            }
  34.            else {
  35.                try { 
  36.                  topWindow.focus();
  37.                }
  38.                catch ( e ) {               
  39.                }
  40.            }
  41.    }
  42.    else {
  43.         var newOptions = { callback: reminderFox_networkSynchronizeCallback, clearMailLabelCallback: reminderFox_clearMailLabelCallback, processRemindersCallback: reminderFox_initializeReminderFoxHourly  };              
  44.         window.openDialog("chrome://reminderfox/content/addreminder-dialog.xul",
  45.             "addreminder-dialog", "chrome,centerscreen,resizable,dialog=no", "reminders", newOptions);
  46.     }    
  47.     reminderFox_lastStatusBarClick = new Date().getTime();
  48. }
  49.  
  50. function reminderFox_clearMailLabelCallback(messageID) {
  51.         reminderFox_clearLabelByMessageID( messageID);
  52. }
  53.  
  54. function reminderFox_openOptionsDialog() {
  55.    var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  56.    var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  57.    var topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxOptions");
  58.   
  59.    if (topWindow) {
  60.            try {
  61.              topWindow.focus();
  62.            }
  63.            catch ( e ) {
  64.            }
  65.    }
  66.    else {
  67.         window.openDialog('chrome://reminderFox/content/options/options.xul', 'reminderFox-options', 'chrome');
  68.     }
  69. }
  70.  
  71. function reminderFox_openQuickAlarmDialog() {
  72.     window.openDialog('chrome://reminderFox/content/alarms/quickAlarmDialog.xul', 'quickAlarm', 'chrome,dialog=no');
  73. }
  74.  
  75.  
  76.  
  77.  
  78. // Launches the 'edit reminder' dialog, fills in Reminders list
  79. function reminderFox_openAddTodosDialog(closeIfOpen) {
  80.    var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  81.    var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  82.    var topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxEdit");
  83.  
  84.    if (topWindow) {
  85.         var currentClickTime = new Date().getTime();
  86.         if ( reminderFox_lastStatusBarClick != null &&  
  87.             ( (currentClickTime - reminderFox_lastStatusBarClick ) < 700 ) ) {
  88.                 closeIfOpen = false;
  89.          }
  90.            if ( closeIfOpen != null && closeIfOpen == true ) {
  91.                topWindow.close();
  92.            }
  93.            else {
  94.                try { 
  95.                  topWindow.focus();
  96.                }
  97.                catch ( e ) {               
  98.                }
  99.            }
  100.    }
  101.    else {
  102.         var newOptions = { callback: reminderFox_networkSynchronizeCallback, clearMailLabelCallback: reminderFox_clearMailLabelCallback, processRemindersCallback: reminderFox_initializeReminderFoxHourly    };     
  103.     window.openDialog("chrome://reminderfox/content/addreminder-dialog.xul", 
  104.         "addreminder-dialog", "chrome,centerscreen,resizable,dialog=no", "todos", newOptions);
  105.     }
  106.     
  107.     reminderFox_lastStatusBarClick = new Date().getTime();
  108. }
  109.  
  110. function reminderFox_openDoubleClickDialog(event) {
  111.     if (event.button == 0) {
  112.         var defaultEditType = REMINDER_FOX_DEFAULT_EDIT_DEFAULT;            
  113.         try {
  114.             defaultEditType = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_DEFAULT_EDIT);
  115.         } catch(e) {
  116.         }    
  117.         if ( defaultEditType == "todos" )  {
  118.             reminderFox_openAddTodosDialog(true);
  119.         }
  120.         else {
  121.             reminderFox_openAddRemindersDialog(true);
  122.         }
  123.     }
  124. }
  125.  
  126.  
  127.  
  128. function  reminderFox_processAlarm( recentReminderOrTodo, isReminder, listName ) { 
  129.     var alarmInfo = null;
  130.     var changed = false;
  131.     var alarmTime = null;
  132.     var lastSnoozeTime = null;
  133.     
  134.     var newDate = new Date( recentReminderOrTodo.date.getFullYear(), recentReminderOrTodo.date.getMonth(), recentReminderOrTodo.date.getDate(), 
  135.         recentReminderOrTodo.date.getHours(), recentReminderOrTodo.date.getMinutes() );
  136.     if ( recentReminderOrTodo.allDayEvent ) {
  137.         newDate.setHours( 0, 0 );
  138.     }
  139.     var mins =     newDate.getMinutes();
  140.     var alarmMinutes = null;
  141.     alarmMinutes = reminderFox_getAlarmInMinutes( recentReminderOrTodo.alarm );
  142.     
  143.     reminderFox_logMessageLevel("alarm: reminder date: " + newDate + "; alarmMinutes: " + alarmMinutes , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  144.     
  145.     // dump: if a RUC=2 reminder, and no snooze...  maybe just always alarm?
  146.     if ( alarmMinutes != null ) { 
  147.         newDate.setMinutes( mins - alarmMinutes );
  148.         alarmTime = newDate.getTime();    
  149.         if ( recentReminderOrTodo.snoozeTime != null ) { // if this alarm has been snoozed, then get its snooze time        
  150.             var snoozeAlarmTime = recentReminderOrTodo.snoozeTime;
  151.             var index = snoozeAlarmTime.indexOf( ';' );
  152.             if ( index != -1 ) {
  153.                 lastSnoozeTime = snoozeAlarmTime.substring( index + 1);            
  154.                 snoozeAlarmTime = snoozeAlarmTime.substring( 0, index );                
  155.                 // separate out: -PT120M
  156.                 lastSnoozeTime = lastSnoozeTime.substring( 2, lastSnoozeTime.length-1);            
  157.             }            
  158.             
  159.             if ( snoozeAlarmTime > alarmTime ) {
  160.                 alarmTime = snoozeAlarmTime;
  161.             }
  162.             else {
  163.                 // this is an old snooze time...  older than the current alarm, so it will never execute.  Clear it.
  164.                 //changed = true;
  165.                 // update: actually this will fail, for repeating reminders as upcoming occurrences would cause this
  166.                 // conditional to be hit and incorrectly clear the snooze time
  167.                 //recentReminderOrTodo.snoozeTime = null;
  168.             }
  169.         }
  170.     }
  171.     else { // if the alarm can not be retrieved properly, return (unless a snooze time is available)        
  172.         if ( recentReminderOrTodo.snoozeTime != null ) {
  173.             var snoozeAlarmTime = recentReminderOrTodo.snoozeTime;
  174.             var index = snoozeAlarmTime.indexOf( ';' );
  175.             if ( index != -1 ) {
  176.                 lastSnoozeTime = snoozeAlarmTime.substring( index + 1);
  177.                 snoozeAlarmTime = snoozeAlarmTime.subSring( 0, index );
  178.                 // separate out: -PT120M
  179.                 lastSnoozeTime = lastSnoozeTime.substring( 2, lastSnoozeTime.length-1);                
  180.             }    
  181.             alarmTime = snoozeAlarmTime;
  182.         }
  183.         else {
  184.             return changed;
  185.         }
  186.     }
  187.         
  188.     var currentTime = new Date().getTime();
  189.     var missedAlarm = false;
  190.     var timeDifference = alarmTime - currentTime;
  191.     
  192.     reminderFox_logMessageLevel("\n\n**************\nProcess Alarm: " + recentReminderOrTodo.date + "\n" + recentReminderOrTodo.summary +"\n" +  
  193.         "alarmMinutes; " + alarmMinutes + " --- alarmTime: " + alarmTime + " == currentTime: " + currentTime + 
  194.         "timeDiff: " + timeDifference + "\nlastAck: " + recentReminderOrTodo.alarmLastAcknowledge + "; Listname: " + listName , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  195.  
  196.     if ( timeDifference < 0 ) {
  197.         // check acknowledge
  198.         var ackDate = new Date();
  199.         ackDate.setTime( recentReminderOrTodo.alarmLastAcknowledge + "\n" );
  200.         if ( recentReminderOrTodo.alarmLastAcknowledge != null  &&  // don't check alarms of old-style reminders (i.e. they have no ack)
  201.              recentReminderOrTodo.alarmLastAcknowledge < alarmTime ) {
  202.              // this past alarm was never acknowledged; let's do it now
  203.              timeDifference = 0;
  204.              missedAlarm = true;
  205.         }
  206.     }
  207.     
  208.     // allow for a minute time buffer
  209.     if ( timeDifference < 0 && timeDifference >= -60000 ) {
  210.         timeDifference = 0;
  211.     }
  212.     
  213.     // check if the time difference occurs in the next 60 minutes
  214.     var timeDifferenceInMinutes = 0;
  215.     if ( timeDifference != 0 ) {
  216.         timeDifferenceInMinutes = timeDifference/60000;
  217.     }
  218.  
  219.     if ( timeDifferenceInMinutes >= 0 && timeDifferenceInMinutes  <= 60 ) {        
  220.         var windowEnumerator =  reminderFox_getWindowEnumerator();
  221.         if (windowEnumerator.hasMoreElements()) {
  222.             var oldestWindow = windowEnumerator.getNext();
  223.                          
  224.             // check alarm list
  225.             var alarmReminderId = recentReminderOrTodo.id;
  226.  
  227.             // if good - add to alarm list
  228.             var found = false;
  229.             for ( var i = 0; i < oldestWindow.reminderFox_alarmList.length && !found; i++ ) {
  230.                 var currentAlarmObject =  oldestWindow.reminderFox_alarmList[i];
  231.                 
  232.                 var currentAlarmId =currentAlarmObject .alarmId;
  233.                 if ( currentAlarmId== alarmReminderId ) {            
  234.                     // found an existing alarm set for this reminder...  
  235.                     if ( currentAlarmObject.snoozed ) { 
  236.                         // if it's been SNOOZED; then ignore as that snooze is going to go off no matter what
  237.                         found = true;
  238.                         break;
  239.                     }                                
  240.                 
  241.                     var currentAlarmTime = currentAlarmObject.timeOfAlarm; 
  242.                     var alarmTimeDiff = alarmTime - currentAlarmTime;
  243.                     
  244.                     if ( (alarmTimeDiff < -60000 || alarmTimeDiff >  60000) && !missedAlarm) {
  245.                         // times are different; delete old and add new (only if this is not a missed alarm - b/c we'll just show the upcoming alarm instead)
  246.                         reminderFox_removeElement( oldestWindow.reminderFox_alarmList, i);
  247.                         reminderFox_logMessageLevel( "alarm: Remove alarm" , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  248.                         break;
  249.                     }
  250.                     else {
  251.                         // times are close enough (within a minute); we don't need to add to the list
  252.                         found = true;
  253.                     }
  254.                 }
  255.             }            
  256.             if ( !found ) {
  257.                 // add him
  258.                 reminderFox_logMessageLevel( "alarm: Setting alarm: " +recentReminderOrTodo.summary, REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  259.                 
  260.                 // if this was a snoozed alarm (in the ICS file) then mark him as snoozed
  261.                 var isSnoozed = false;
  262.                 if ( recentReminderOrTodo.snoozeTime != null ) {
  263.                     isSnoozed = true;                    
  264.                 }
  265.                 oldestWindow.reminderFox_alarmList[oldestWindow.reminderFox_alarmList.length]  = { alarmId: alarmReminderId,       timeOfAlarm: alarmTime,         snoozed: isSnoozed };
  266.                 var missedAlarmString = "false";
  267.                 if ( missedAlarm  ) {  
  268.                     missedAlarmString = "true";
  269.                 }
  270.                 var isReminderString = "true";
  271.                 if ( !isReminder ) {
  272.                     isReminderString = "false";
  273.                 }
  274.                 if ( listName == null ){
  275.                     listName = "";
  276.                 }
  277.                 var isTodo = false;    
  278.                 if (isReminder != "true" && isReminder != true ) {
  279.                     isTodo = true;
  280.                 }        
  281.                 
  282.                 
  283.                 var newAlarm = { 
  284.                     alarmTabPanel: null,
  285.                     alarmRecentReminder: recentReminderOrTodo,
  286.                     alarmSnoozeTime: lastSnoozeTime,
  287.                     alarmListName: listName,
  288.                     alarmTimeString: alarmTime,
  289.                     alarmIsReminder: isReminderString,
  290.                     alarmIsTodo: isTodo,
  291.                     alarmAlarmMissed: missedAlarmString,
  292.                     synccallback: reminderFox_networkSynchronizeCallback,
  293.                     clearLabelCallback: reminderFox_clearMailLabelCallback,
  294.                     alarmCurrentAlarmId: alarmReminderId,
  295.                     reminderTime: recentReminderOrTodo.date.getTime(),
  296.                     reminderTimeDifference : timeDifference 
  297.                 };
  298.                         
  299.                         
  300.                 if ( timeDifference <= 0 || missedAlarm ) {
  301.                     // do nothing; will return missed alarm
  302.                     alarmInfo = newAlarm;
  303.                 
  304.                 }
  305.                 else {
  306.                     var alarmInfoArray = new Array();
  307.                     alarmInfoArray[0] = newAlarm;
  308.                     oldestWindow.setTimeout("reminderFox_showMissedAlarmsSnooze(" + 
  309.                         alarmInfoArray[0].alarmSnoozeTime + ",'" +
  310.                         alarmInfoArray[0].alarmRecentReminder.id + "',\"" +
  311.                         alarmInfoArray[0].alarmListName + "\"," +
  312.                         alarmInfoArray[0].alarmTimeString + "," +
  313.                         alarmInfoArray[0].alarmIsReminder + "," +
  314.                         alarmInfoArray[0].alarmIsTodo + "," +
  315.                         alarmInfoArray[0].alarmAlarmMissed + "," +
  316.                         alarmInfoArray[0].reminderTime + "," +
  317.                         alarmInfoArray[0].reminderTimeDifference + ")",
  318.                         timeDifference);
  319.                 }
  320.             }
  321.         }
  322.     }
  323.     
  324.     return alarmInfo;
  325. }
  326.  
  327.  
  328. function reminderFox_showMissedAlarmsSnooze( alarmSnoozeTime, alarmRecentReminderID, alarmListName, 
  329.     alarmTimeString, alarmIsReminder, alarmIsTodo, alarmAlarmMissed, reminderTime, 
  330.     reminderTimeDifference ) { 
  331.     
  332.     var isReminder = false;
  333.     if ( alarmIsReminder == 1 ) {
  334.         isReminder = true;
  335.     }
  336.     
  337.     var isTodo = false;
  338.     if ( alarmIsTodo == 1 ) {
  339.         isTodo = true;
  340.     }
  341.     
  342.     var reminderOrTodo = null;
  343.     if ( isReminder == "true" || isReminder == true ) {
  344.         reminderOrTodo =    reminderFox_getRemindersById( alarmRecentReminderID);
  345.     }
  346.     else {
  347.         reminderOrTodo =    reminderFox_getSpecificTodoById( alarmRecentReminderID);
  348.     }
  349.     
  350.     var alarmMissed = false;
  351.     if ( alarmAlarmMissed == 1 ) {
  352.         alarmMissed = true;
  353.     }
  354.     
  355.     var newAlarm = { 
  356.         quickAlarmText : null,
  357.         alarmTabPanel: null,
  358.         alarmRecentReminder: reminderOrTodo,
  359.         alarmSnoozeTime: alarmSnoozeTime,
  360.         alarmListName: alarmListName,
  361.         alarmTimeString: alarmTimeString,
  362.         alarmIsReminder: isReminder,
  363.         alarmIsTodo: isTodo,
  364.         alarmAlarmMissed: alarmMissed,
  365.         synccallback: reminderFox_networkSynchronizeCallback,
  366.         clearLabelCallback: reminderFox_clearMailLabelCallback,
  367.         alarmCurrentAlarmId: alarmRecentReminderID,
  368.         reminderTime: reminderTime,
  369.         reminderTimeDifference : reminderTimeDifference 
  370.     };
  371.     
  372.      var alarmInfos = new Array();
  373.      alarmInfos[0] = newAlarm;
  374.      reminderFox_showMissedAlarms( alarmInfos );
  375. }
  376.  
  377.  
  378. function reminderFox_showMissedAlarmsSnooze2( alarmSnoozeTime, alarmRecentReminderID, alarmListName, 
  379.     alarmTimeString, alarmIsReminder, alarmIsTodo, alarmAlarmMissed, reminderTime, 
  380.     reminderTimeDifference ) { 
  381.     var isReminder = false;
  382.     if ( alarmIsReminder == 1 ) {
  383.         isReminder = true;
  384.     }
  385.     
  386.     var isTodo = false;
  387.     if ( alarmIsTodo == 1 ) {
  388.         isTodo = true;
  389.     }
  390.         
  391.     
  392.     if ( isReminder == "true" || isReminder == true ) {
  393.         reminderOrTodo =    reminderFox_getRemindersById( alarmRecentReminderID);
  394.     }
  395.     else {
  396.         reminderOrTodo =    reminderFox_getSpecificTodoById( alarmRecentReminderID);
  397.     }
  398.         
  399.     var alarmMissed = false;
  400.     if ( alarmAlarmMissed == 1 ) {
  401.         alarmMissed = true;
  402.     }
  403.     
  404.     var newAlarm = { 
  405.         quickAlarmText : null,
  406.         alarmTabPanel: null,
  407.         alarmRecentReminder: reminderOrTodo,
  408.         alarmSnoozeTime: alarmSnoozeTime,
  409.         alarmListName: alarmListName,
  410.         alarmTimeString: alarmTimeString,
  411.         alarmIsReminder: isReminder,
  412.         alarmIsTodo: isTodo,
  413.         alarmAlarmMissed: alarmMissed,
  414.         synccallback: reminderFox_networkSynchronizeCallback,
  415.         clearLabelCallback: reminderFox_clearMailLabelCallback,
  416.         alarmCurrentAlarmId: alarmRecentReminderID,
  417.         reminderTime: reminderTime,
  418.         reminderTimeDifference : reminderTimeDifference 
  419.     };
  420.     
  421.      var alarmInfos = new Array();
  422.      alarmInfos[0] = newAlarm;
  423.     reminderFox_openAlarmWindow(alarmInfos);
  424. }
  425.  
  426.  
  427.  
  428.  
  429.  
  430. function reminderFox_showMissedAlarms( alarmInfos ) {
  431.     var alarmArray = new Array();
  432.     for (var k = 0; k < alarmInfos.length; k++) {
  433.         var alarmInfo = alarmInfos[k];
  434.         
  435.         if ( alarmInfo.quickAlarmText != null ) { // a quick alarm
  436.             alarmArray[alarmArray.length] = alarmInfo;
  437.             continue;
  438.         }
  439.         
  440.         var reminderdateTime = alarmInfo.reminderTime;
  441.         var alarmReminderId = alarmInfo.alarmCurrentAlarmId;
  442.         var isReminder = alarmInfo.alarmIsReminder;
  443.         var alarmTime = alarmInfo.alarmTimeString;
  444.         var missedAlarm = alarmInfo.alarmAlarmMissed;
  445.         
  446.         // only show alarm if reminder still exists and it has not been marked complete
  447.         //  (the user could have deleted/completed it since last setting the alarm timeout)
  448.         var reminderOrTodo = alarmInfo.alarmRecentReminder;
  449.         if (isReminder == "true" || isReminder == true ) {
  450.             reminderOrTodo = reminderFox_getRemindersById(alarmReminderId);
  451.         }
  452.         else {
  453.             reminderOrTodo = reminderFox_getSpecificTodoById(alarmReminderId);
  454.         }
  455.     
  456.         if (reminderOrTodo != null) {
  457.             var completed = false;
  458.             if (isReminder == "true" || isReminder == true) {
  459.                 reminderOrTodo = reminderFox_cloneReminderFoxEvent(reminderOrTodo);
  460.                 reminderOrTodo.date.setTime(reminderdateTime);
  461.                 completed = reminderFox_isCompletedForDate(reminderOrTodo, reminderOrTodo.date);
  462.             }
  463.             else {
  464.                 completed = reminderOrTodo.completedDate != null;
  465.                 reminderOrTodo = reminderFox_cloneReminderFoxTodo(reminderOrTodo);
  466.                 reminderOrTodo.date.setTime(reminderdateTime);
  467.             }
  468.             if (!completed) {
  469.                 // only show this reminder if it has not already been acknowledged
  470.                 var resultbool = (reminderOrTodo.alarmLastAcknowledge <= alarmTime);
  471.                 reminderFox_logMessageLevel("alarm: last acknowlege: " + reminderOrTodo.alarmLastAcknowledge + " <=? " + alarmTime + " ; result = " + (reminderOrTodo.alarmLastAcknowledge <= alarmTime), REMINDER_FOX_LOG_LEVEL_SUPER_FINE); //TODO
  472.                 if (reminderOrTodo.alarmLastAcknowledge == null || reminderOrTodo.alarmLastAcknowledge <= alarmTime) {
  473.                     var windowEnumerator = reminderFox_getWindowEnumerator();
  474.                     if (windowEnumerator.hasMoreElements()) {
  475.                         var oldestWindow = windowEnumerator.getNext();
  476.                         for (var i = 0; i < oldestWindow.reminderFox_alarmList.length; i++) {
  477.                             var currentAlarmId = oldestWindow.reminderFox_alarmList[i].alarmId;
  478.                             var snooze = false;
  479.                             if (currentAlarmId == alarmReminderId) {
  480.                                 if (oldestWindow.reminderFox_alarmList[i].snoozed) {
  481.                                     snooze = true;
  482.                                 }
  483.                                 var currentAlarmTime;
  484.                                 if (snooze) {
  485.                                     var alarmTimeInt = parseInt(alarmTime);
  486.                                     var actualCurrentTime = new Date().getTime();
  487.                                     
  488.                                     // if you snooze an alarm for a long value (like 28 days), mozilla calls the setTimeout immediately.  We need
  489.                                     // to check against that (they probably have some bug when an int value gets too big)
  490.                                     actualCurrentTime = actualCurrentTime + 2000; // add 2 seconds for a small buffer
  491.                                     var diffcheck = actualCurrentTime < alarmTimeInt;
  492.                                     if (actualCurrentTime < alarmTimeInt) {
  493.                                         reminderFox_logMessageLevel("alarm: current time is less than alarm time; not showing alarm.  Current time " + (actualCurrentTime - 2000) + "; alarm time set for: " + alarmTimeInt, REMINDER_FOX_LOG_LEVEL_SUPER_FINE); //TODO
  494.                                         continue;
  495.                                     }
  496.                                     
  497.                                     
  498.                                     currentAlarmTime = parseInt(alarmTime);
  499.                                 }
  500.                                 else {
  501.                                     currentAlarmTime = oldestWindow.reminderFox_alarmList[i].timeOfAlarm;
  502.                                 }
  503.                                 
  504.                                 var alarmTimeDiff = alarmTime - currentAlarmTime;
  505.                                 
  506.                                 reminderFox_logMessageLevel("alarm: original alarm time: " + alarmTime + "; current alarm time: " + currentAlarmTime + ";  alarmTimeDiff: " + alarmTimeDiff, REMINDER_FOX_LOG_LEVEL_SUPER_FINE); //TODO
  507.                                 // ensure that the current stored alarm time is the same as the alarm time this function was called with.  
  508.                                 // This check is in case the user changed the alarm time after the first timeout had been issued.  You only 
  509.                                 // want to show one alert at the last time the user selected
  510.                                 if (alarmTimeDiff >= -60000 && alarmTimeDiff <= 60000) {
  511.  
  512.                                     if (!snooze && missedAlarm == "false") { // don't check, if this is a past alarm (times won't match because it was set to go off not at current time, but a previous time)                            
  513.                                         // secondary check - in case of FireFox setTimeout Bug;        
  514.                                         // check if the current time is about  when the alarm was set for
  515.                                         var currentSystemTime = new Date().getTime();
  516.                                         var alarmSystemTimeDiff = alarmTime - currentSystemTime;
  517.                                         if (alarmSystemTimeDiff < -60000 || alarmSystemTimeDiff > 60000) {
  518.                                             reminderFox_logMessageLevel("alarm: system time diff failed check; returning: " + alarmSystemTimeDiff, REMINDER_FOX_LOG_LEVEL_SUPER_FINE); //TODO
  519.                                             continue;
  520.                                         }
  521.                                     }
  522.                                     
  523.                                 // Mozilla bug: it seems that if you open two alarm dialog windows at the same time, only one of the loadAlarm() functions gets called 
  524.                                 // from the new window.  So we introduce a small second delay between opening each alarm - so if you have several alarms set to go off
  525.                                 // at the same time, you will always see them properly and not get a blank window in one of them
  526.                                 var time = new Date().getTime();         
  527.                                 reminderFox_logMessageLevel( "alarm: time: " + time + "; lastalarmtime" +reminderFox_lastAlarmTime + " ; " +  reminderFox_ALARM_DELAY    , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  528.                                 alarmInfo.alarmRecentReminder = reminderOrTodo;                
  529.                                 if ( alarmInfos.length > 1 ||  // if there's multiple reminders; continue in here.  Only if there is 1 reminder would we want to set the delay
  530.                                     (reminderFox_lastAlarmTime == null || (  time > (reminderFox_lastAlarmTime + reminderFox_ALARM_DELAY) ) ) ) {
  531.                                         reminderFox_lastAlarmTime = time;
  532.                                         reminderFox_logMessageLevel( "alarm: opening alarm dialog: " + reminderOrTodo.summary   , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  533.                                         alarmArray[alarmArray.length] = alarmInfo;
  534.                                     }
  535.                                     else {
  536.                                         reminderFox_logMessageLevel( "alarm: Setting time out..."   , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  537.                                         
  538.                                         oldestWindow.setTimeout("reminderFox_showMissedAlarmsSnooze2(" + 
  539.                                             alarmInfo.alarmSnoozeTime + ",'" +
  540.                                             alarmInfo.alarmRecentReminder.id + "',\"" +
  541.                                             alarmInfo.alarmListName + "\"," +
  542.                                             alarmInfo.alarmTimeString + "," +
  543.                                             alarmInfo.alarmIsReminder + "," +
  544.                                             alarmInfo.alarmIsTodo + "," +
  545.                                             alarmInfo.alarmAlarmMissed + "," +
  546.                                             alarmInfo.reminderTime + "," +
  547.                                             alarmInfo.reminderTimeDifference + ")",
  548.                                             reminderFox_ALARM_DELAY);
  549.                                     }
  550.                                         
  551.                                     break;
  552.                                 }
  553.                             }
  554.                         }
  555.                     }
  556.                 }
  557.                 else {
  558.                 }
  559.             }
  560.         }
  561.     }
  562.     
  563.     reminderFox_openAlarmWindow( alarmArray, true );
  564.             
  565. }
  566.  
  567. function reminderFox_openAlarmWindow(alarmArray, ignoreCheck) {
  568.     var showAlarmsInTabs= reminderFox_getPreferenceValue( REMINDER_FOX_ALARMS_SHOW_IN_TABS );
  569.     
  570.     // go through all options
  571.     if ( alarmArray != null && alarmArray.length > 0 ) {
  572.        var windowManager = Components.classes['@mozilla.org/appshell/window-mediator;1'].getService();
  573.        var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
  574.        var topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxAlarmDialog");
  575.        
  576.         var time = new Date().getTime();         
  577.         reminderFox_logMessageLevel( "alarm2: time: " + time + "; lastalarmtime" +reminderFox_lastAlarmTime + " ; " +  reminderFox_ALARM_DELAY    , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  578.         if ( ignoreCheck || alarmArray.length > 1 ||  // if there's multiple reminders; continue in here.  Only if there is 1 reminder would we want to set the delay
  579.             (reminderFox_lastAlarmTime == null || (  time > (reminderFox_lastAlarmTime + reminderFox_ALARM_DELAY) ) ) ) {
  580.             reminderFox_lastAlarmTime = time;
  581.             if (showAlarmsInTabs && topWindow) {                                         
  582.                try { 
  583.                     // close and reopen
  584.                     var selectedIndex = topWindow.getRF_alarmIndex();
  585.                     var existingAlarmArray = topWindow.getRF_AlarmArray();
  586.                     // see if this quick alarm is already being shown...
  587.                     for ( var j = alarmArray.length-1; j >= 0; j-- ) {
  588.                         if ( alarmArray[j].quickAlarmText != null ) {
  589.                             for ( var k = 0; k < existingAlarmArray.length; k++ ) {
  590.                                 if ( existingAlarmArray[k].quickAlarmText != null &&
  591.                                     existingAlarmArray[k].quickAlarmText == alarmArray[j].quickAlarmText ) {
  592.                                     // alarm already exists; remove from current list
  593.                                     reminderFox_removeElement(alarmArray, j);
  594.                                     break;
  595.                                 }
  596.                             }
  597.                         }
  598.                         // see if this alarm is already being shown
  599.                         else if ( alarmArray[j].alarmRecentReminder != null ) {
  600.                             for ( var k = 0; k < existingAlarmArray.length; k++ ) {
  601.                                 if ( existingAlarmArray[k].alarmRecentReminder != null &&
  602.                                     existingAlarmArray[k].alarmRecentReminder.id == alarmArray[j].alarmRecentReminder.id ) {
  603.                                     // alarm already exists; remove from current list
  604.                                     reminderFox_removeElement(alarmArray, j);
  605.                                     break;
  606.                                 }
  607.                             }
  608.                         }
  609.                     }
  610.                     if ( alarmArray.length > 0 ) {
  611.                         // close/reopen
  612.                         topWindow.reminderFox_reopeningWindow = true;
  613.                         topWindow.close();
  614.                         for ( var j = 0; j < alarmArray.length; j++ ) {
  615.                             existingAlarmArray[existingAlarmArray.length] = alarmArray[j];
  616.                         }
  617.                         
  618.                         var newOptions = {  alarmInfos: existingAlarmArray, showMissedAlarmsSnoozeCallback : reminderFox_showMissedAlarms}
  619.                         window.openDialog("chrome://reminderfox/content/alarms/alarmDialog.xul",
  620.                             "alarmOptionsDialog", "chrome,resizable,dialog=no", newOptions);
  621.                         topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxAlarmDialog");
  622.                         if ( topWindow != null ) {
  623.                             topWindow.focus();
  624.                         }
  625.                     }
  626.                    }
  627.                    catch ( e ) {               
  628.                    }
  629.                  }
  630.                  else {
  631.                     if ( !showAlarmsInTabs ) {
  632.                         // go through all alarms and open in separate windows
  633.                         for ( var i = 0; i < alarmArray.length; i++ ) {
  634.                             var singleArray = new Array();
  635.                             singleArray[0] = alarmArray[i];
  636.                             var newOptions = {  alarmInfos: singleArray, showMissedAlarmsSnoozeCallback : reminderFox_showMissedAlarmsSnooze}
  637.                             window.openDialog("chrome://reminderfox/content/alarms/alarmDialog.xul",
  638.                                 "alarmOptionsDialog"+new Date().getTime() + i, "chrome,resizable,dialog=no", newOptions);
  639.                             topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxAlarmDialog");
  640.                             if ( topWindow != null ) {
  641.                                 topWindow.focus();
  642.                             }
  643.                         }
  644.                     }
  645.                     else {
  646.                         var newOptions = {  alarmInfos: alarmArray, showMissedAlarmsSnoozeCallback : reminderFox_showMissedAlarmsSnooze}
  647.                         //we don't use alarmOptionsDialog + date =- sometimes showing a separate window
  648.                         window.openDialog("chrome://reminderfox/content/alarms/alarmDialog.xul",
  649.                             "alarmOptionsDialog", "chrome,resizable,dialog=no", newOptions);
  650.                         topWindow = windowManagerInterface.getMostRecentWindow("window:reminderFoxAlarmDialog");
  651.                         if ( topWindow != null ) {
  652.                             topWindow.focus();
  653.                         }
  654.                     }
  655.                 }
  656.             }
  657.             else {
  658.                 var windowEnumerator =  reminderFox_getWindowEnumerator();
  659.                 if (windowEnumerator.hasMoreElements()) {
  660.                     var oldestWindow = windowEnumerator.getNext();        
  661.                     reminderFox_logMessageLevel( "alarm: Setting time out..."   , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  662.                     var alarmInfo = alarmArray[0];
  663.                     if ( alarmInfo.quickAlarmText != null ) {
  664.                         oldestWindow.setTimeout('reminderFox_showQuickAlarm("'+alarmInfo.quickAlarmText+'","'+alarmInfo.alarmSnoozeTime+'")', reminderFox_ALARM_DELAY);
  665.                     }
  666.                     else {
  667.                         oldestWindow.setTimeout("reminderFox_showMissedAlarmsSnooze2(" + 
  668.                             alarmInfo.alarmSnoozeTime + ",'" +
  669.                             alarmInfo.alarmRecentReminder.id + "',\"" +
  670.                             alarmInfo.alarmListName + "\"," +
  671.                             alarmInfo.alarmTimeString + "," +
  672.                             alarmInfo.alarmIsReminder + "," +
  673.                             alarmInfo.alarmIsTodo + "," +
  674.                             alarmInfo.alarmAlarmMissed + "," +
  675.                             alarmInfo.reminderTime + "," +
  676.                             alarmInfo.reminderTimeDifference + ")",
  677.                             reminderFox_ALARM_DELAY);
  678.                         }
  679.                     }
  680.             }
  681.                 
  682.         }
  683.                 
  684. }
  685.  
  686.  
  687. function reminderFox_showQuickAlarm( lastAlarmText, lastSnoozeTime, lastQuickAlarmNotes) {
  688.  
  689.     dump( "SHOW QUICK ALARM BEING CALLED...\n" );
  690.      reminderFox_logMessageLevel( new Date()  + "INSIDE SHOW QUICKALARM: " + lastAlarmText + " - " +  lastSnoozeTime + " - "  + lastQuickAlarmNotes , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  691.  
  692.     var newAlarm = { 
  693.         quickAlarmText : lastAlarmText,
  694.         quickAlarmNotes : lastQuickAlarmNotes,
  695.         alarmTabPanel: null,
  696.         alarmRecentReminder: null,
  697.         alarmSnoozeTime: lastSnoozeTime,
  698.         alarmListName: null,
  699.         alarmTimeString: null,
  700.         alarmIsReminder: false,
  701.         alarmIsTodo: false,
  702.         alarmAlarmMissed: false,
  703.         synccallback: reminderFox_networkSynchronizeCallback,
  704.         clearLabelCallback: reminderFox_clearMailLabelCallback,
  705.         alarmCurrentAlarmId: null,
  706.         reminderTime: null,
  707.         reminderTimeDifference : null 
  708.     };
  709.         
  710.     var alarmArray = new Array();
  711.     alarmArray[0]= newAlarm;
  712.     reminderFox_openAlarmWindow(alarmArray);
  713. }
  714.  
  715. // Launches the 'edit reminder' dialog, fills in Reminders list
  716. function reminderFox_openAboutReminderFoxDialog() {
  717.     window.openDialog("chrome://reminderfox/content/about.xul", "about", "chrome,centerscreen");
  718. }
  719.  
  720.  
  721. function reminderFox_processRecentReminders(processQuickAlarms){ 
  722.     var changed = false;
  723.     var alarmInfos = new Array();
  724.     var NUM_OF_PAST_DAYS_TO_PROCESS = 90; // needs to be less than weekly reminder so Completed mark isn't cleared...  
  725.     // the real fix is to check if the reminder you are clearing occurs today as well; if so don't clear the mark
  726.     // Update 11/24/09: I don't think this is true anymore; we don't clear completed mark - we set last completed date; 
  727.     // changing to look in the past 90(?) days for alarms, RUC, etc; that should be long enough
  728.     var NUM_OF_DAYS_AHEAD_FOR_ALARM = 15; // let's look a couple weeks ahead in case an alarm is set to go off
  729.     var i, j;
  730.     
  731.     var alarmsEnabled = true;
  732.     var alertType;
  733.     try {
  734.         alertType = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_ENABLE_ALERT_PREF);
  735.     } 
  736.     catch (e) {
  737.         alertType = REMINDER_FOX_ENABLE_ALERT_PREF_ALL;
  738.     }
  739.     if (alertType.indexOf(REMINDER_FOX_SUSPEND_ALERT_PREF) != -1) {
  740.         alarmsEnabled = false;
  741.     }
  742.     
  743.     
  744.     var reminderEvents = reminderFox_getReminderEvents();
  745.     var reminder;
  746.     
  747.     // set dates to search during the last week only
  748.     var todaysDate = new Date();
  749.     var startDate = new Date();
  750.     var endDateAlarmCheck = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
  751.     endDateAlarmCheck.setDate(startDate.getDate() + NUM_OF_DAYS_AHEAD_FOR_ALARM);
  752.     startDate.setDate(startDate.getDate() - NUM_OF_PAST_DAYS_TO_PROCESS);
  753.     for (i = 0; i < reminderEvents.length; i++) {
  754.         reminder = reminderEvents[i];
  755.         
  756.         // pass in false to not limit repeating instances returned; otherwise, 
  757.         // we only get first 8 weekly/daily instances - this causes an issue if we are looking back
  758.         // 3 months behind; we would not get the current instances for alarms, etc
  759.         var allReminders = reminderFox_getAllRemindersInDateRange(reminder, startDate, endDateAlarmCheck, false);  
  760.         if (allReminders.length == 0) {
  761.             var dateCompare = reminderFox_compareDates(reminder.date, todaysDate);
  762.             if (reminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED && dateCompare == -1) {
  763.                 allReminders = new Array();
  764.                 allReminders[0] = reminder;
  765.             }
  766.         }
  767.         
  768.         
  769.         for (j = 0; j < allReminders.length; j++) {
  770.             var recentReminder = allReminders[j];
  771.             var dateCompare = reminderFox_compareDates(recentReminder.date, todaysDate);
  772.             // if a reminder is set to Remind Until Complete (and it's already happened) set to today's date to check for alarm        
  773.             if (recentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED && dateCompare == -1) {
  774.                 recentReminder = reminderFox_cloneReminderFoxEvent(recentReminder);
  775.                 recentReminder.date = new Date(todaysDate.getFullYear(), todaysDate.getMonth(), todaysDate.getDate(), recentReminder.date.getHours(), recentReminder.date.getMinutes());
  776.                 dateCompare = 0; // set as today's date    
  777.             }
  778.             
  779.             reminderFox_logMessageLevel("alarm: recent alarm" + j + ": " + recentReminder.summary + " -- " + recentReminder.alarm + " -- " + alarmsEnabled, REMINDER_FOX_LOG_LEVEL_SUPER_FINE); //TODO
  780.             // check the alert for future and past reminders (for missed alerts)
  781.             if (recentReminder.alarm != null && alarmsEnabled && !reminderFox_isCompletedForDate(recentReminder, recentReminder.date)) {
  782.                 var missedAlarmInfo = reminderFox_processAlarm(recentReminder, true, null);  // soo here we might have an old one 
  783.                 // showing in alarm, and then set a new one to go off the next hour...  how do I stop that?
  784.                 // when showing alarms, need to check existing list if it's the same reminder ID?  and don't show new one?
  785.                 // or remove old one...
  786.                 if (missedAlarmInfo != null) {
  787.                     alarmInfos[alarmInfos.length] = missedAlarmInfo;  
  788.                 }
  789.             }
  790.             
  791.             // if the reminder happened in the past, we want to see if it should be move to RemindUntilComplete
  792.             if (dateCompare == -1) {
  793.                 // check for any RemindUntilComplete - if found, set it to be shown in today's list of reminders
  794.                 if (recentReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_TO_BE_MARKED) {
  795.                     if (reminder.recurrence.type == REMINDER_RECURRENCE_ONETIME || recentReminder.lastModified != null) {
  796.                         var modifiedDate = reminderFox_getStringAsDate(recentReminder.lastModified);
  797.                         // if you last modified this on or  before the reminder date, then set it as RUC;
  798.                         // otherwise if you've modified this after the reminder date (such as setting it complete)
  799.                         // then leave it alone and don't set it as RUC (unless it's a one-timer... then we'll just move it to RUC
  800.                         // since that is probably what they intended)
  801.                         if (reminder.recurrence.type == REMINDER_RECURRENCE_ONETIME ||
  802.                         (reminderFox_compareDates(modifiedDate, recentReminder.date) != 1 &&
  803.                         !reminderFox_isCompletedForDate(recentReminder, recentReminder.date))) { // don't change if it's Complete
  804.                             reminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED;
  805.                             changed = true;
  806.                             reminder.lastModified = reminderFox_getDateAsString(todaysDate);
  807.                         }
  808.                     }
  809.                     else {
  810.                         reminder.remindUntilCompleted = REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED;
  811.                         changed = true;
  812.                         reminder.lastModified = reminderFox_getDateAsString(todaysDate);
  813.                     }
  814.                 }
  815.             }
  816.         }
  817.     }
  818.     
  819.     // now process todos
  820.     var allTodosHash = reminderFox_getAllTodosInDateRange(startDate, endDateAlarmCheck);
  821.     
  822.     for (var n in allTodosHash) {
  823.         var allTodos = allTodosHash[n];
  824.         for (i = 0; i < allTodos.length; i++) {
  825.             var todo = allTodos[i];
  826.             // check the alert for future and past reminders (for missed alerts)
  827.             if (todo.alarm != null && alarmsEnabled && todo.completedDate == null) {
  828.                 //                var snoozeCleared = reminderFox_processAlarm( todo, false, n);
  829.                 //                if ( snoozeCleared ) {
  830.                 //                    changed = true;
  831.                 //                }
  832.                 var missedAlarmInfo = reminderFox_processAlarm(todo, false, n);
  833.                 if (missedAlarmInfo != null) {
  834.                     alarmInfos[alarmInfos.length] = missedAlarmInfo;
  835.                 }
  836.             }
  837.         }
  838.     }
  839.     
  840.     if ( processQuickAlarms ) {
  841.         var quickAlarmArray = reminderFox_processQuickAlarms(true);
  842.         for ( var q = 0; q < quickAlarmArray.length; q++ ) {
  843.             alarmInfos[alarmInfos.length] = quickAlarmArray[q];
  844.         }
  845.     }
  846.     
  847.     // for any alarms:
  848.     if (alarmInfos != null && alarmInfos.length > 0) {
  849.         reminderFox_showMissedAlarms(alarmInfos);
  850.     }
  851.     
  852.     return changed;
  853. }
  854.     
  855.     
  856.  
  857.  
  858.  
  859.  
  860. function reminderFox_createToolTip(todayRemindersArr, upcomingRemindersArr) {
  861.     var j;
  862.     var currentNode;
  863.     var todayDescription;
  864.     var upcomingDescription;
  865.     var spacer;
  866.     var todoDescription;
  867.     
  868.     // we'll set the icon depending on if there's current, upcoming, 
  869.     // or no reminders
  870.      var icon = document.getElementById('reminderFox-statusLabel');
  871.      icon.setAttribute("status", "noReminders");
  872.  
  873.      var todosArr = reminderFox_getVisibleTodos();
  874.          
  875.      // clear old tooltips
  876.     var todayBox = document.getElementById("todaysRemindersBox");
  877.     if ( todayBox != null ) {
  878.          while (todayBox.hasChildNodes()) {
  879.              todayBox.removeChild(todayBox.firstChild);
  880.            }        
  881.     }
  882.                     
  883.     var upcomingBox = document.getElementById("upcomingRemindersBox");
  884.     if ( upcomingBox != null ) {
  885.          while (upcomingBox.hasChildNodes()) {
  886.              upcomingBox.removeChild(upcomingBox.firstChild);
  887.            }        
  888.     }
  889.     
  890.     var todoBox = document.getElementById("todosBox");
  891.     if ( todoBox != null ) {
  892.          while (todoBox.hasChildNodes()) {
  893.              todoBox.removeChild(todoBox.firstChild);
  894.            }    
  895.     }
  896.         
  897.         
  898.     // remove old tooltip box
  899.     var tooltipChildren = document.getElementById("todosTooltip");        
  900.     while (tooltipChildren.hasChildNodes()) {
  901.          tooltipChildren.removeChild(tooltipChildren.firstChild);
  902.     }        
  903.     
  904.     
  905.     // remove old reminders box
  906.     var tooltipChildrenReminders = document.getElementById("tooltipChildrenReminders");
  907.     while (tooltipChildrenReminders.hasChildNodes()) {
  908.          tooltipChildrenReminders.removeChild(tooltipChildrenReminders.firstChild);
  909.     }        
  910.  
  911.     var showReminders = true;            
  912.     try {
  913.         showReminders = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_SHOW_REMINDERS_IN_TOOLTIP);
  914.     } catch(e) {
  915.     }            
  916.  
  917.     var showTooltips = true;            
  918.     try {
  919.         showTooltips = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_SHOW_TODOS_IN_TOOLTIP);
  920.     } catch(e) {
  921.     }            
  922.      
  923.      var tooltipWrapLength;
  924.  
  925.      if ( todosArr != null && showReminders && showTooltips) {
  926.          tooltipWrapLength = reminderFox_TOOLTIP_WITH_TODOS_LINE_LENGTH;
  927.      }
  928.      else {
  929.          tooltipWrapLength = reminderFox_TOOLTIP_LINE_LENGTH;
  930.      }
  931.  
  932.      if ( showReminders ) { 
  933.              todayDescription = document.createElement("description");
  934.             todayDescription.setAttribute("id", "todayRemindersDescription");
  935.             todayDescription.setAttribute("value",reminderFox_getBundle().getString("rf.main.tooltip.todaysReminders.title"));
  936.             todayDescription.setAttribute("style", "font-weight:bold;");
  937.             tooltipChildrenReminders.appendChild(todayDescription);
  938.     
  939.             var todayVbox = document.createElement("vbox");
  940.             todayVbox.setAttribute("id", "todaysRemindersBox");
  941.             tooltipChildrenReminders.appendChild(todayVbox);
  942.                  
  943.             spacer =      document.createElement("spacer");    
  944.              spacer.setAttribute("id", "reminderSpacer");        
  945.              spacer.setAttribute("height", "4px");        
  946.             tooltipChildrenReminders.appendChild(spacer);             
  947.          
  948.               upcomingDescription = document.createElement("description");
  949.             upcomingDescription.setAttribute("id", "upcomingRemindersDescription");
  950.             upcomingDescription.setAttribute("value", reminderFox_getBundle().getString("rf.main.tooltip.upcomingReminders.title"));
  951.             upcomingDescription.setAttribute("style", "font-weight:bold;");
  952.             tooltipChildrenReminders.appendChild(upcomingDescription);
  953.  
  954.             var upcomingVbox = document.createElement("vbox");
  955.             upcomingVbox.setAttribute("id", "upcomingRemindersBox");
  956.             tooltipChildrenReminders.appendChild(upcomingVbox);
  957.  
  958.              reminderFox_populateTodayToolTip(todayRemindersArr, tooltipWrapLength );
  959.              reminderFox_populateUpcomingToolTip(upcomingRemindersArr, tooltipWrapLength);
  960.     }
  961.     
  962.     
  963.     
  964.     
  965.     if ( showTooltips && todosArr != null ) {        
  966.          // make sure ToDo's are at the start of the list         
  967.         var todos = todosArr[REMINDER_FOX_DEFAULT_TODOS_CATEGORY];
  968.         if ( todos != null && todos.length > 0) {         
  969.             reminderFox_populateTodoToolTip(todos, (tooltipWrapLength - 13), reminderFox_getBundle().getString( "rf.main.tooltip.todos.title" ) );    
  970.         }
  971.         
  972.         // iterate over all of the ToDo lists in the order that the user defined in the preferences
  973.          var todoLists = reminderFox_getPreferenceValue( REMINDER_FOX_TODO_LISTS );
  974.          if ( todoLists != null && todoLists.length > 0) {     
  975.              var subscriptions = reminderFox_getSubscriptions();        
  976.              var todoListsArray = todoLists.split(",");
  977.              for ( var j = 0; j < todoListsArray.length; j++ ) {
  978.                 var n = todoListsArray[j]; // name
  979.                 var todos = todosArr[n];
  980.                 if ( todos != null && todos.length > 0) {        
  981.                     if ( subscriptions[n] == null ) { // ignore subscriptions                    
  982.                         reminderFox_populateTodoToolTip(todos, (tooltipWrapLength - 13), n);    
  983.                     }
  984.                 }
  985.             }    
  986.          }         
  987.     }
  988.          
  989.     if ( todayRemindersArr.length > 0 ) {
  990.         icon.setAttribute("status", "currentReminder");
  991.     }
  992.     else if ( upcomingRemindersArr.length > 0 ) {
  993.         icon.setAttribute("status", "upcomingReminder");
  994.     }    
  995. }
  996.  
  997. function reminderFox_populateTodayToolTip(remindersArr, tooltipWrapLength) {
  998.     var lblparent = document.getElementById("todaysRemindersBox");    
  999.     // Get the template from the user preference    
  1000.     var template = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_TODAYS_REMINDERS_LABEL);
  1001.     reminderFox_populateToolTip(remindersArr, tooltipWrapLength, lblparent, template ) ;
  1002. }
  1003.  
  1004.  
  1005. function reminderFox_populateUpcomingToolTip( remindersArr, tooltipWrapLength) {
  1006.     var lblparent = document.getElementById("upcomingRemindersBox");
  1007.     // Get the template from the user preference    
  1008.     var template = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_UPCOMING_REMINDERS_LABEL);
  1009.     reminderFox_populateToolTip(remindersArr, tooltipWrapLength, lblparent, template ) ;
  1010. }
  1011.  
  1012. function reminderFox_populateToolTip(remindersArr, tooltipWrapLength, lblparent, template )  {
  1013.     var j;
  1014.     var remLabel;
  1015.     if (remindersArr.length > 0 ) {
  1016.         var lineWrappedIndent = 5;    
  1017.         for(var i=0; i < remindersArr.length; i++) {        
  1018.             var startIndex = 0;
  1019.             var completeRemainingString = reminderFox_populateReminderLabel(remindersArr[i], template, remindersArr[i].date);    
  1020.             var stringSeparatedByNewlines = completeRemainingString.split("\\n");
  1021.             for ( var z = 0; z < stringSeparatedByNewlines.length; z++ ) { 
  1022.                 var remainingString = stringSeparatedByNewlines[z];
  1023.                 var afterFirst = false;
  1024.                 while ( remainingString.length > tooltipWrapLength  ) {                
  1025.                     // go back to last whitespace
  1026.                     var lastIndex = remainingString.lastIndexOf( ' ', tooltipWrapLength );
  1027.                     var forceLineBreak = false;
  1028.                     if ( lastIndex == -1 ) {
  1029.                         forceLineBreak = true;
  1030.                         lastIndex = tooltipWrapLength + 1;
  1031.                     }
  1032.                     if ( lastIndex != -1 ) {
  1033.                         var curStr = remainingString.substring( 0, lastIndex );
  1034.                         // after the first line, for any extra lines we will indent some.This makes
  1035.                         // the entry look nice when wrapping to the following lines
  1036.                         if ( afterFirst )  {
  1037.                             j = 0;
  1038.                             while ( j < lineWrappedIndent ) {
  1039.                                 curStr = " " + curStr;
  1040.                                 j++;
  1041.                             }
  1042.                         }    
  1043.                                 
  1044.                         remLabel = document.createElement("description");
  1045.                         remLabel.setAttribute("value", curStr);
  1046.                         if ( remindersArr[i].priority == REMINDER_PRIORITY_IMPORTANT) { 
  1047.                             remLabel.setAttribute("style", "color: red;");
  1048.                         }
  1049.                         else {
  1050.                             remLabel.removeAttribute( "style" );
  1051.                         }
  1052.                         lblparent.appendChild(remLabel);
  1053.                         afterFirst = true;
  1054.                     }
  1055.                     
  1056.                     if ( forceLineBreak ) {
  1057.                         startIndex = lastIndex;
  1058.                     }
  1059.                     else {
  1060.                         startIndex = lastIndex + 1;
  1061.                     }
  1062.                     remainingString = remainingString.substring( startIndex );                                                  
  1063.                 }
  1064.                 if ( afterFirst )  {
  1065.                        j = 0;
  1066.                        while ( j < lineWrappedIndent ) {
  1067.                            remainingString = " " + remainingString;
  1068.                            j++;
  1069.                        }
  1070.                 }                        
  1071.                 reminderFox_addItemToTooltip( remindersArr[i], true, remainingString, lblparent );
  1072.             }
  1073.         }
  1074.     } else {
  1075.         var noneLabel = document.createElement("description");
  1076.         noneLabel.setAttribute("value",reminderFox_getBundle().getString( "rf.main.tooltip.reminders.none" ) );  
  1077.         lblparent.appendChild(noneLabel);
  1078.     }
  1079. }
  1080.  
  1081. function reminderFox_addItemToTooltip( reminderOrTodo, isReminder, labelText, parentElement ) {
  1082.     var hasNotes = reminderOrTodo.notes != null && reminderOrTodo.notes != "";
  1083.     var isRUC = false;
  1084.     var remLabel;
  1085.     if ( isReminder ) {
  1086.         isRUC = reminderOrTodo.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED;
  1087.     }
  1088.     if ( !hasNotes && !isRUC ) {   // no image needed
  1089.             remLabel = document.createElement("description");
  1090.             remLabel.setAttribute("value", labelText);
  1091.             if ( reminderOrTodo.priority == REMINDER_PRIORITY_IMPORTANT) { 
  1092.                 remLabel.setAttribute("style", "color: red;");
  1093.             }
  1094.             else {
  1095.                 remLabel.removeAttribute( "style" );
  1096.             }
  1097.             parentElement.appendChild(remLabel);
  1098.     }
  1099.     else {
  1100.             // create image box
  1101.             var hbox = document.createElement("hbox");            
  1102.             remLabel = document.createElement("description");
  1103.             var image1;
  1104.             var vbox = document.createElement("vbox");    
  1105.             var spacer =     document.createElement("spacer");    
  1106.             spacer.setAttribute("flex", "1" )    
  1107.             vbox.appendChild( spacer );
  1108.             
  1109.             if ( ! (isRUC && hasNotes) ) {
  1110.                 // if only 1 image  (remindUntilCompleted / notes )
  1111.                 if ( hasNotes ) {
  1112.                     image1 = document.createElement("image");
  1113.                     image1.setAttribute("src", REMINDER_FOX_NOTES_IMAGE );
  1114.                     vbox.appendChild( image1 );
  1115.                 }
  1116.                 else {
  1117.                     image1 = document.createElement("image");
  1118.                     image1.setAttribute("src", REMINDER_FOX_REMIND_UNTIL_COMPLETED_IMAGE );
  1119.                     vbox.appendChild( image1 );
  1120.                 }
  1121.             }
  1122.             else {                
  1123.                 // if multi image
  1124.                 var imagehbox = document.createElement("hbox");            
  1125.                 image1 = document.createElement("image");
  1126.                 image1.setAttribute("src", REMINDER_FOX_NOTES_IMAGE );
  1127.                 imagehbox.appendChild( image1 );        
  1128.                             
  1129.                 var image2 = document.createElement("image");
  1130.                 image2.setAttribute("src", REMINDER_FOX_REMIND_UNTIL_COMPLETED_IMAGE );
  1131.                 imagehbox.appendChild( image2 );
  1132.                 
  1133.                 vbox.appendChild(imagehbox );
  1134.             }
  1135.             
  1136.             
  1137.             // end multi
  1138.             vbox.appendChild( spacer );
  1139.  
  1140.             remLabel.setAttribute("value", labelText);
  1141.  
  1142.             if ( reminderOrTodo.priority == REMINDER_PRIORITY_IMPORTANT) { 
  1143.                 remLabel.setAttribute("style", "color: red;");
  1144.             }
  1145.             else {
  1146.                 remLabel.removeAttribute( "style" );
  1147.             }
  1148.             hbox.appendChild( remLabel );
  1149.             hbox.appendChild( vbox );
  1150.             
  1151.             parentElement.appendChild(hbox);
  1152.     }
  1153. }
  1154.  
  1155.  
  1156. function reminderFox_populateTodoToolTip( todosArr, tooltipWrapLength, listName) {
  1157.     var containerVbox = document.getElementById("todosTooltip");
  1158.     
  1159.     var tooltipVbox = document.createElement("vbox");
  1160.     var todoDescription = document.createElement("description");
  1161.     todoDescription.setAttribute("id", "todoDescription");
  1162.     todoDescription.setAttribute("value", listName);
  1163.     todoDescription.setAttribute("style", "font-weight:bold;");
  1164.     tooltipVbox.appendChild(todoDescription);
  1165.     
  1166.     var todosBox = document.createElement("vbox");
  1167.     todosBox.setAttribute("id", "todosBox");
  1168.     tooltipVbox.appendChild(todosBox);                
  1169.     
  1170.     var spacer = document.createElement("spacer");
  1171.     spacer.setAttribute("height", "4px");
  1172.     tooltipVbox.appendChild(spacer);                    
  1173.     
  1174.     containerVbox.appendChild(tooltipVbox);        
  1175.                     
  1176.     var j;
  1177.     var remLabel;
  1178.     var template = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_UPCOMING_REMINDERS_LABEL);
  1179.     if (todosArr.length > 0 ) {
  1180.         for(var i=0; i < todosArr.length; i++) {    
  1181.             var lineWrappedIndent = 5;
  1182.             var startIndex = 0;
  1183.             var completeRemainingString = null;
  1184.             if ( todosArr[i].date != null ) {
  1185.                 completeRemainingString = reminderFox_populateReminderLabel(todosArr[i], template, todosArr[i].date);    
  1186.             }
  1187.             else {
  1188.                  completeRemainingString = todosArr[i].summary;
  1189.             }            
  1190.             
  1191.             var stringSeparatedByNewlines = completeRemainingString.split("\\n");
  1192.             for ( var z = 0; z < stringSeparatedByNewlines.length; z++ ) { 
  1193.                 var remainingString = stringSeparatedByNewlines[z];
  1194.                 var afterFirst = false;
  1195.                 while ( remainingString.length > tooltipWrapLength ) {                
  1196.                     // go back to last whitespace
  1197.                     var lastIndex = remainingString.lastIndexOf( ' ', tooltipWrapLength );
  1198.                     var forceLineBreak = false;
  1199.                     if ( lastIndex == -1 ) {
  1200.                         forceLineBreak = true;
  1201.                         lastIndex = tooltipWrapLength + 1;
  1202.                     }                    
  1203.                     if ( lastIndex != -1 ) {
  1204.                         var curStr = remainingString.substring( 0, lastIndex );
  1205.                         // after the first line, for any extra lines we will indent some.  This makes
  1206.                         // the entry look nice when wrapping to the following lines
  1207.                         if ( afterFirst )  {
  1208.                             j = 0;
  1209.                             while ( j < lineWrappedIndent ) {
  1210.                                 curStr = " " + curStr;
  1211.                                 j++;
  1212.                             }
  1213.                         }                    
  1214.                         
  1215.                         remLabel = document.createElement("description");
  1216.                         remLabel.setAttribute("value", curStr);
  1217.                         if ( todosArr[i].priority == REMINDER_PRIORITY_IMPORTANT ) {
  1218.                             remLabel.setAttribute("style", "color: red;");
  1219.                         }
  1220.                         else {
  1221.                         remLabel.removeAttribute( "style" );
  1222.                         }
  1223.                         todosBox.appendChild(remLabel);
  1224.                         afterFirst = true;
  1225.                     }
  1226.                                     
  1227.                     if ( forceLineBreak ) {
  1228.                         startIndex = lastIndex;
  1229.                     }
  1230.                     else {
  1231.                         startIndex = lastIndex + 1;
  1232.                     }
  1233.                     remainingString = remainingString.substring( startIndex );                                                            
  1234.                 }
  1235.                 if ( afterFirst )  {
  1236.                        j = 0;
  1237.                        while ( j < lineWrappedIndent ) {
  1238.                            remainingString = " " + remainingString;
  1239.                            j++;
  1240.                        }
  1241.                 }
  1242.                 reminderFox_addItemToTooltip( todosArr[i], false, remainingString, todosBox );
  1243.             }
  1244.         }
  1245.     } else {
  1246.         var noneLabel = document.createElement("description");
  1247.         noneLabel.setAttribute("value", reminderFox_getBundle().getString( "rf.main.tooltip.reminders.none" ) );  
  1248.         todosBox.appendChild(noneLabel);
  1249.     }
  1250. }
  1251.  
  1252.  
  1253. function reminderFox_getTodaysAndUpcomingReminders() {
  1254.     var i, j, x;
  1255.     var reminder, todayReminder, upcomingReminder, allReminders;
  1256.     var endIndex, index;
  1257.     var reminderEvents =     reminderFox_getReminderEvents();
  1258.     var todaysReminders = new Array();
  1259.     var upcomingReminders = new Array();
  1260.  
  1261.     var upcomingReminderDays =reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + UPCOMING_REMINDER_DAYS_PREF);
  1262.     if ( upcomingReminderDays > 364 ) {
  1263.         upcomingReminderDays = 364;
  1264.     }
  1265.     var todaysDate = new Date();
  1266.     var REPEAT_UPCOMING_OCCURRENCES;
  1267.     try {
  1268.         REPEAT_UPCOMING_OCCURRENCES =  reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_REPEAT_UPCOMING_OCCURRENCES);
  1269.     } catch(e) {
  1270.          REPEAT_UPCOMING_OCCURRENCES = -1;
  1271.     }        
  1272.  
  1273.     var endDate  = new Date( todaysDate.getFullYear(), todaysDate.getMonth(), todaysDate.getDate() );
  1274.     endDate.setDate( endDate.getDate() + upcomingReminderDays );
  1275.     for( i = 0; i < reminderEvents.length; i++) {
  1276.         todayReminder = null;
  1277.         reminder = reminderEvents[i];
  1278.         
  1279.         // handle reminders marked Remind Until Complete as today reminders
  1280.         if ( reminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED ) {
  1281.              todayReminder = reminderFox_cloneReminderFoxEvent( reminder );             
  1282.             todayReminder.date  = new Date( todaysDate.getFullYear(), todaysDate.getMonth(), todaysDate.getDate(), 
  1283.                                  todayReminder.date.getHours(), todayReminder.date.getMinutes() );            
  1284.                                  
  1285.             if ( !reminderFox_isCompletedForDate( todayReminder, todayReminder.date ) ) {    
  1286.                 todayReminder  = reminderFox_processReminderDescription(todayReminder, todayReminder.date.getFullYear(), false);    
  1287.                 index = reminderFox_getSortNewUpcomingReminderIndex( todaysReminders, todayReminder );    
  1288.                 reminderFox_insertIntoArray( todaysReminders, todayReminder, index );            
  1289.             }                                                     
  1290.          }        
  1291.         
  1292.         
  1293.         // for performance reasons, sort all the yearly items first, which should generally be in order; then do the repeating ones afterwards,
  1294.         // as they will need to be inserted all over the arrays
  1295.         if ( reminder.recurrence.type  == REMINDER_RECURRENCE_YEARLY || 
  1296.                 reminder.recurrence.type  == REMINDER_RECURRENCE_ONETIME ) {
  1297.             allReminders = reminderFox_getAllRemindersInDateRange( reminder,  todaysDate, endDate, true );
  1298.             endIndex = 0;
  1299.             if ( allReminders.length > 0 ) {
  1300.                 endIndex  = allReminders.length;
  1301.             }
  1302.             
  1303.             // have to have a check for -1 --> show all occurrences            
  1304.             if ( allReminders.length > 0) {
  1305.                  if ( !(allReminders.length == 1  &&  REPEAT_UPCOMING_OCCURRENCES >=1 ) )  {            
  1306.                     for ( x = 0; x < allReminders.length; x++ ) {
  1307.                         if ( reminderFox_compareDates( allReminders[x].date, todaysDate) != -1 ) {
  1308.                             break;
  1309.                         }
  1310.                     }
  1311.                     if ( REPEAT_UPCOMING_OCCURRENCES == -1 ) {
  1312.                         endIndex = allReminders.length;
  1313.                     }
  1314.                     else {
  1315.                         endIndex = x + REPEAT_UPCOMING_OCCURRENCES;
  1316.                         if ( endIndex > allReminders.length ) {
  1317.                             endIndex = allReminders.length;
  1318.                         }
  1319.                     }
  1320.                  }
  1321.             }
  1322.             
  1323.             for (  j = 0; j < endIndex; j++ ) {                    
  1324.                 upcomingReminder = allReminders[j];
  1325.                 
  1326.                 if ( j == 0 ) { // special checking for first reminder
  1327.                     if ( reminderFox_isCompletedForDate( upcomingReminder, upcomingReminder.date )  ) {
  1328.                         continue;  //ignore first complete
  1329.                     }
  1330.                     
  1331.                     // if it's marked as RUC and the date is not in the future, than we've already handled this as Today; skip it
  1332.                     if (upcomingReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED  ) {
  1333.                         if ( reminderFox_compareDates(  upcomingReminder.date, todaysDate ) != 1 ) {
  1334.                             continue;                        
  1335.                         }
  1336.                     }
  1337.                     else {
  1338.                         // handle today's reminders
  1339.                         if (reminderFox_compareDates(  upcomingReminder.date, todaysDate ) == 0 ) {
  1340.                             todayReminder = reminderFox_cloneReminderFoxEvent( upcomingReminder );
  1341.                             todayReminder  = reminderFox_processReminderDescription(todayReminder, todayReminder.date.getFullYear(), false);
  1342.                             index = reminderFox_getSortNewUpcomingReminderIndex( todaysReminders, todayReminder );    
  1343.                             reminderFox_insertIntoArray( todaysReminders, todayReminder, index );            
  1344.                             continue;    
  1345.                         }       
  1346.                     }
  1347.                 }
  1348.  
  1349.                 upcomingReminder  = reminderFox_processReminderDescription(upcomingReminder, upcomingReminder.date.getFullYear(), false);            
  1350.                 index = reminderFox_getSortNewUpcomingReminderIndex( upcomingReminders, upcomingReminder );    
  1351.                 reminderFox_insertIntoArray( upcomingReminders, upcomingReminder, index );
  1352.             }
  1353.         }
  1354.     }
  1355.     
  1356.     // now sort repeating items...
  1357.     for( i = 0; i < reminderEvents.length; i++) {
  1358.         todayReminder = null;
  1359.         reminder = reminderEvents[i];
  1360.         if ( reminder.recurrence.type  != REMINDER_RECURRENCE_YEARLY &&
  1361.                 reminder.recurrence.type  != REMINDER_RECURRENCE_ONETIME ) {
  1362.             allReminders = reminderFox_getAllRemindersInDateRange( reminder,  todaysDate, endDate, true );
  1363.             // do the filtering here...
  1364.             endIndex = 0;
  1365.             if ( allReminders.length > 0 ) {
  1366.                 endIndex  = allReminders.length;
  1367.             }
  1368.             
  1369.             // have to have a check for -1 --> show all occurrences            
  1370.             if ( allReminders.length > 0) {
  1371.                  if ( !(allReminders.length == 1  &&  REPEAT_UPCOMING_OCCURRENCES >=1 ) )  {            
  1372.                     for ( x = 0; x < allReminders.length; x++ ) {
  1373.                         if ( reminderFox_compareDates( allReminders[x].date, todaysDate) != -1 ) {
  1374.                             break;
  1375.                         }
  1376.                     }
  1377.                     if ( REPEAT_UPCOMING_OCCURRENCES == -1 ) {
  1378.                         endIndex = allReminders.length;
  1379.                     }
  1380.                     else {
  1381.                         endIndex = x + REPEAT_UPCOMING_OCCURRENCES;
  1382.                         if ( endIndex > allReminders.length ) {
  1383.                             endIndex = allReminders.length;
  1384.                         }
  1385.                     }
  1386.                  }
  1387.             }                        
  1388.                                                 
  1389.            for (  j = 0; j < endIndex; j++ ) {    
  1390.                 upcomingReminder = allReminders[j];
  1391.                 
  1392.                 if ( j == 0 ) { // special checking for first reminder
  1393.                     if ( reminderFox_isCompletedForDate( upcomingReminder, upcomingReminder.date )  ) {
  1394.                         continue;  //ignore first complete
  1395.                     }
  1396.                     
  1397.                     // if it's marked as RUC and the date is not in the future, than we've already handled this as Today; skip it
  1398.                     if (upcomingReminder.remindUntilCompleted == REMINDERFOX_REMIND_UNTIL_COMPLETE_MARKED  ) {
  1399.                         if ( reminderFox_compareDates(  upcomingReminder.date, todaysDate ) != 1 ) {
  1400.                             continue;                        
  1401.                         }
  1402.                     }
  1403.                     else {
  1404.                         // handle today's reminders
  1405.                         if (reminderFox_compareDates(  upcomingReminder.date, todaysDate ) == 0 ) {
  1406.                             todayReminder = reminderFox_cloneReminderFoxEvent( upcomingReminder );
  1407.                             todayReminder  = reminderFox_processReminderDescription(todayReminder, todayReminder.date.getFullYear(), false);
  1408.                             index = reminderFox_getSortNewUpcomingReminderIndex( todaysReminders, todayReminder );    
  1409.                             reminderFox_insertIntoArray( todaysReminders, todayReminder, index );                        
  1410.                             continue;    
  1411.                         }       
  1412.                     }
  1413.                 }
  1414.                 
  1415.                 // add upcoming reminder
  1416.                 upcomingReminder  = reminderFox_processReminderDescription(upcomingReminder, upcomingReminder.date.getFullYear(), false);            
  1417.                     
  1418.                 index = reminderFox_getSortNewUpcomingReminderIndex( upcomingReminders, upcomingReminder );    
  1419.                 reminderFox_insertIntoArray( upcomingReminders, upcomingReminder, index );
  1420.             }
  1421.         }
  1422.     }
  1423.  
  1424.     return  { today: todaysReminders, upcoming: upcomingReminders  };         
  1425. }
  1426.  
  1427.  
  1428. function reminderFox_getVisibleTodos2() {
  1429.     var todosArr = reminderFox_getReminderTodos();  //  iterate over ALL  todos    
  1430.     var visibleTodosHashMap = { };
  1431.     var sortMap;
  1432.     
  1433.     var upcomingReminderDays =reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + UPCOMING_REMINDER_DAYS_PREF);
  1434.     if ( upcomingReminderDays > 364 ) {
  1435.         upcomingReminderDays = 364;
  1436.     }
  1437.     var endDate  = new Date(  );
  1438.     endDate.setDate( endDate.getDate() + upcomingReminderDays );    
  1439.     var todaysDate = new Date();
  1440.     for ( var n in todosArr ) {
  1441.         var todos = todosArr[n];
  1442.  
  1443.         if ( todos != null ) {
  1444.              if ( visibleTodosHashMap[n] == null ) {
  1445.                 visibleTodosHashMap[n] = new Array();
  1446.             }
  1447.             if ( sortMap == null ) {
  1448.                 sortMap = new Array();
  1449.                 var sortColumnsStr = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_SORT_COLUMNS_PREF);
  1450.                  if ( sortColumnsStr != null && sortColumnsStr != ""  ) {
  1451.                      var sortColumnsStrArray = sortColumnsStr.split(",");
  1452.                      for ( var i = 0; i < sortColumnsStrArray.length; i++ ) { 
  1453.                         var listName =  sortColumnsStrArray[i];
  1454.                         i++;
  1455.                         var sortCol = sortColumnsStrArray[i];
  1456.                         i++;
  1457.                         var sortDir = parseInt( sortColumnsStrArray[i] );
  1458.                         sortMap[listName] = { sortColumn: sortCol, sortDirection:  sortDir };                    
  1459.                      }
  1460.                  }
  1461.             }
  1462.             var currentTodosList  = visibleTodosHashMap[n];        
  1463.             for(var  i = 0; i < todos.length; i++) {
  1464.                                                 
  1465.                 // only show if the todo has not been completed and the user wants to show it in the tooltip
  1466.                  if ( !todos[i].showInTooltip || todos[i].completedDate != null ) {
  1467.                     continue;
  1468.                 }        
  1469.                 else     if ( todos[i].date != null && reminderFox_compareDates( todos[i].date, endDate ) == 1)  {
  1470.                     // only show if the date is less than the user's Number of Upcoming Days
  1471.                      continue;            
  1472.                  }            
  1473.  
  1474. //                                                   
  1475. //                else if ( todos[i].date != null ) {        
  1476. //                    // if no recurrence...  then just show it as before; otherwise, monkey around with showNext_X_Occcurrences
  1477. //                    if ( todos[i].recurrence.type == ONETIME ) {
  1478. //                        if ( reminderFox_compareDates( todos[i].date, endDate ) == 1)  {
  1479. //                            // only show if the date is less than the user's Number of Upcoming Days
  1480. //                             continue;    
  1481. //                        }        
  1482. //                    }    
  1483. //                    else {    
  1484. //                        var allReminders = reminderFox_getAllRemindersInDateRange( todos[i],  todaysDate, endDate, true );
  1485. //                        for ( var j = 0; j < allReminders.length; j++ ) {            
  1486. //                            var validTodo  = reminderFox_processReminderDescription(allReminders[j], todaysDate.getFullYear(), true);                                
  1487. //                            currentTodosList[currentTodosList.length] =validTodo;
  1488. //                            
  1489. //                    }
  1490. //                }
  1491. //                else {
  1492. //                    var validTodo  = reminderFox_processReminderDescription(todos[i], todaysDate.getFullYear(), true);                                
  1493. //                    currentTodosList[currentTodosList.length] =validTodo;
  1494. //                }
  1495.             }
  1496.         
  1497.             if ( sortMap[n] != null ) {                
  1498.                 var sortedArray = new Array(currentTodosList.length );
  1499.                 for ( var i = 0; i < currentTodosList.length; i++ ) {
  1500.                     sortedArray[i] = currentTodosList[i];
  1501.                     sortedArray[i].originalIndex = i;
  1502.                 }                                
  1503.                 reminderFox_quick_sort( sortedArray, sortMap[n].sortColumn, sortMap[n].sortDirection );
  1504.                 visibleTodosHashMap[n] = sortedArray;
  1505.             }
  1506.         }
  1507.     }         
  1508.     
  1509.     return visibleTodosHashMap;
  1510. }
  1511.  
  1512.  
  1513. function reminderFox_getVisibleTodos() {
  1514.     var todosArr = reminderFox_getReminderTodos();  //  iterate over  ALL  todos    
  1515.     var visibleTodosHashMap = { };
  1516.     var sortMap;
  1517.     
  1518.     var upcomingReminderDays =reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + UPCOMING_REMINDER_DAYS_PREF);
  1519.     if ( upcomingReminderDays > 364 ) {
  1520.         upcomingReminderDays = 364;
  1521.     }
  1522.     var endDate  = new Date(  );
  1523.     endDate.setDate( endDate.getDate() + upcomingReminderDays );    
  1524.     var todaysDate = new Date();
  1525.     for ( var n in todosArr ) {
  1526.         var todos = todosArr[n];
  1527.  
  1528.         if ( todos != null ) {
  1529.              if ( visibleTodosHashMap[n] == null ) {
  1530.                 visibleTodosHashMap[n] = new Array();
  1531.             }
  1532.             if ( sortMap == null ) {
  1533.                 sortMap = new Array();
  1534.                 var sortColumnsStr = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_SORT_COLUMNS_PREF);
  1535.                  if ( sortColumnsStr != null && sortColumnsStr != ""  ) {
  1536.                      var sortColumnsStrArray = sortColumnsStr.split(",");
  1537.                      for ( var i = 0; i < sortColumnsStrArray.length; i++ ) { 
  1538.                         var listName =  sortColumnsStrArray[i];
  1539.                         i++;
  1540.                         var sortCol = sortColumnsStrArray[i];
  1541.                         i++;
  1542.                         var sortDir = parseInt( sortColumnsStrArray[i] );
  1543.                         sortMap[listName] = { sortColumn: sortCol, sortDirection:  sortDir };                    
  1544.                      }
  1545.                  }
  1546.             }
  1547.             var currentTodosList  = visibleTodosHashMap[n];        
  1548.             for(var  i = 0; i < todos.length; i++) {
  1549.                 // only show if the todo has not been completed and the user wants to show it in the tooltip
  1550.                  if ( !todos[i].showInTooltip || todos[i].completedDate != null ) {
  1551.                     continue;
  1552.                 }        
  1553.                 else     if ( todos[i].date != null && reminderFox_compareDates( todos[i].date, endDate ) == 1)  {
  1554.                     // only show if the date is less than the user's Number of Upcoming Days
  1555.                      continue;            
  1556.                  }                                                              
  1557.                         
  1558.                 var validTodo  = reminderFox_processReminderDescription(todos[i], todaysDate.getFullYear(), true);                                
  1559.                 currentTodosList[currentTodosList.length] =validTodo;
  1560.             }
  1561.             
  1562.         
  1563.             if ( sortMap[n] != null ) {
  1564.                 
  1565.                 var sortedArray = new Array(currentTodosList.length );
  1566.                 for ( var i = 0; i < currentTodosList.length; i++ ) {
  1567.                     sortedArray[i] = currentTodosList[i];
  1568.                     sortedArray[i].originalIndex = i;
  1569.                 }                                
  1570.                 reminderFox_quick_sort( sortedArray, sortMap[n].sortColumn, sortMap[n].sortDirection );
  1571.                 visibleTodosHashMap[n] = sortedArray;
  1572.             }
  1573.         }
  1574.     }         
  1575.     
  1576.     return visibleTodosHashMap;
  1577. }
  1578.  
  1579.  
  1580. function reminderFox_storeTimeOfLastUpdate() {
  1581.     // output the last time of update for debugging, but only if the
  1582.     // preference already exists
  1583.     try {        
  1584.         reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LAST_UPDATE);
  1585.  
  1586.         var currentDate = new Date();
  1587.         var hours = currentDate.getHours();
  1588.         var mins = currentDate.getMinutes();
  1589.         var secs = currentDate.getSeconds();
  1590.         
  1591.         var readableMins = mins;
  1592.         if ( mins < 10 ) {
  1593.             readableMins = "0" + readableMins;
  1594.         }
  1595.         var readableSecs = secs;
  1596.         if ( secs < 10 ) {
  1597.             readableSecs = "0" + readableSecs;
  1598.         }
  1599.         reminderFox_prefsBranch.setCharPref(REMINDER_FOX_LAST_UPDATE, hours + ":" + readableMins + ":" + readableSecs);    
  1600.     } catch(e) {
  1601.         // pref doesn't exist.  Do nothing.
  1602.     }    
  1603. }
  1604.  
  1605.  
  1606. function reminderFox_moveBox() { 
  1607.     //check if box is ind the right location
  1608.     var toolbar = document.getElementById(reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_TOOLBAR));
  1609.     var box = document.getElementById("reminderFox-statusLabel");
  1610.  
  1611.     var position;
  1612.     try {
  1613.         position = reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_TOOLBAR_POSITION) ;
  1614.     }
  1615.     catch( e ) {
  1616.         position = -1;
  1617.     }
  1618.  
  1619.     //if toolbar doesn't exist move to default location
  1620.     if (!toolbar) {
  1621.         reminderFox_prefsBranch.setIntPref(REMINDER_FOX_TOOLBAR_POSITION, REMINDER_FOX_TOOLBAR_DEFAULT);
  1622.         reminderFox_prefsBranch.setIntPref(REMINDER_FOX_TOOLBAR_POSITION, REMINDER_FOX_TOOLBAR_POSITION_DEFAULT);      
  1623.          return;
  1624.     }
  1625.  
  1626.     // bail if it is in the right place
  1627.     if (reminderFox_indexOf(toolbar,box, false) == position) {
  1628.          return;
  1629.      }
  1630.  
  1631.     //remove us from parent
  1632.     box.parentNode.removeChild(box);
  1633.  
  1634.     reminderFox_insertAtIndex(toolbar, box, position);
  1635.   }
  1636.   
  1637.  
  1638.  function reminderFox_insertAtIndex(aParent, aChild, aIndex)  {
  1639.     var children = aParent.childNodes;
  1640.     if ((children.length == 0) || (aIndex >= children.length) || (aIndex < 0)) {
  1641.       aParent.appendChild(aChild);
  1642.      }
  1643.     else {
  1644.        aParent.insertBefore(aChild, children[aIndex]);
  1645.      }
  1646.   }
  1647.  
  1648. function reminderFox_storeTimeOfLastAlert() {
  1649.     // output the last time of update for debugging, but only if the
  1650.     // preference already exists
  1651.     try {        
  1652.         var currentDate = new Date();        
  1653.         var time = currentDate.getTime();
  1654.         reminderFox_prefsBranch.setCharPref( REMINDER_FOX_LAST_ALERT, time);            
  1655.     } catch(e) {
  1656.         // pref doesn't exist.  Do nothing.
  1657.     }    
  1658. }
  1659.  
  1660. function reminderFox_storeTimeOfLastProcessed() {
  1661.     // output the last time of update for debugging, but only if the
  1662.     // preference already exists
  1663.     try {        
  1664.         var currentDate = new Date();        
  1665.         var time = currentDate.getTime();
  1666.         reminderFox_prefsBranch.setCharPref( REMINDER_FOX_LAST_PROCESSED, time);            
  1667.     } catch(e) {
  1668.         // pref doesn't exist.  Do nothing.
  1669.     }    
  1670. }
  1671.  
  1672. function reminderFox_updateForRemoteChange( statustxtString, actionID) {
  1673.     if ( actionID == 1 ||  // completed successfully (remote and local are equal, or were uploaded)
  1674.         actionID == 2  || // reminders were downloaded,  need to refresh reminders
  1675.         actionID == -1  // connection error - in this case we still need to proces reminders in case enough time has elapsed
  1676.        ) {  
  1677.         var changed = reminderFox_processRecentReminders();     
  1678.         if ( changed ) {
  1679.             // write stuff out
  1680.             reminderFox_writeOutRemindersAndTodos(false);                                
  1681.             reminderFox_syncWrittenChangesToRemote();        
  1682.         }
  1683.         
  1684.         var windowEnumerator =  reminderFox_getWindowEnumerator();
  1685.         if (windowEnumerator.hasMoreElements()) {
  1686.             var oldestWindow = windowEnumerator.getNext();        
  1687.             oldestWindow.reminderFox_updateRemindersInWindow();    
  1688.     
  1689.             oldestWindow.reminderFox_clearRemindersAndTodos();
  1690.             while (windowEnumerator.hasMoreElements()) {
  1691.                 var currentWindow = windowEnumerator.getNext();        
  1692.                 currentWindow.reminderFox_updateRemindersInWindow();        
  1693.                 currentWindow.reminderFox_clearRemindersAndTodos();                        
  1694.             }
  1695.         }
  1696.     }
  1697. }    
  1698.  
  1699. function reminderFox_ensureRemoteRemindersSynchronized( headless ) {  
  1700.  
  1701.     var waitForResponse = false;
  1702.     
  1703.     // sync 'em up 
  1704.     var networkSync = REMINDER_FOX_NETWORK_SYNCHRONIZE_DEFAULT;        
  1705.     try {
  1706.         networkSync = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_NETWORK_SYNCHRONIZE);
  1707.     } catch(e) {
  1708.     }    
  1709.     if ( networkSync ) {
  1710.         if ( headless ) {
  1711.             waitForResponse = true;
  1712.             reminderFox_download_Startup_headless(REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS, reminderFox_updateForRemoteChange);
  1713.         }
  1714.         else {
  1715.             reminderFox_downloadReminders();
  1716.         }
  1717.     }        
  1718.      
  1719.     return waitForResponse;
  1720. }
  1721.  
  1722. // this runs every hour and updates all of the windows with the latest reminders
  1723. function reminderFox_initializeReminderFox(clearReminders) {
  1724.     var windowEnumerator =  reminderFox_getWindowEnumerator();
  1725.     var currentDate;
  1726.     if (windowEnumerator.hasMoreElements()) {
  1727.         var oldestWindow = windowEnumerator.getNext();
  1728.         // if this is the very first (oldest) window opened, then let's process the reminders
  1729.         if ( window == oldestWindow ) {
  1730.             // verify that the correct amount of time has elapsed since last update.   Sometimes due to 
  1731.             // what appears to be a FireFox bug, sometimes a large number of  timeouts are called.  This
  1732.             // ensures that we only process once after the proper amount of time
  1733.             var lastTime =         reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." +  REMINDER_FOX_LAST_PROCESSED);
  1734.             if ( !reminderFox_initialized  ) { 
  1735.                 // the very first time, clear out the last time so that we always run when you start Firefox
  1736.                 lastTime = "";
  1737.                 reminderFox_initialized = true;
  1738.             }
  1739.             currentDate = new Date();
  1740.             var currentTime = currentDate.getTime();
  1741.             var lastTimeElapsed = null;
  1742.             if ( lastTime != null && lastTime != "" )  {
  1743.                 lastTimeElapsed = parseInt(lastTime) + reminderFox_HOUR_TIMEOUT;
  1744.             }
  1745.             reminderFox_logMessageLevel(currentDate + "check - should Initialize: " + (lastTime == null  || lastTime == "" ||  (currentTime+500) >= lastTimeElapsed ) +  " ==  lastTime " + lastTime + " -- currentTime: " + currentTime + " -- lastTimeElapsed: " + lastTimeElapsed  + " - Difference (currentTime+500) - lastTimeElapsed:" + ((currentTime+500) -lastTimeElapsed) , REMINDER_FOX_LOG_LEVEL_FINE);
  1746.             if (lastTime == null  || lastTime == "" ||  (currentTime+500) >= lastTimeElapsed ) {    
  1747.                 var updateWindows = false;
  1748.                 var fileChanged = reminderFox_timeStampHasChanged();
  1749.                 if ( fileChanged != -1 ) { 
  1750.                     reminderFox_storeTimeStamp(fileChanged);                    
  1751.                 }
  1752.  
  1753.                 var waitForResponse = reminderFox_ensureRemoteRemindersSynchronized(true);
  1754.                 
  1755.                 reminderFox_logMessageLevel( "network: waitForResponse:  " + waitForResponse   , REMINDER_FOX_LOG_LEVEL_SUPER_FINE);  //TODO
  1756.                 
  1757.                 var changed = false;
  1758.                 try { 
  1759.                     if ( !waitForResponse ) {
  1760.                         changed = reminderFox_processRecentReminders(true);
  1761.                     }
  1762.                 }
  1763.                 catch ( e ) {
  1764.                 }
  1765.                 if ( changed ) {
  1766.                     updateWindows = true;
  1767.                     // write stuff out
  1768.                     reminderFox_writeOutRemindersAndTodos(false);                                
  1769.                     reminderFox_syncWrittenChangesToRemote();            
  1770.                 }
  1771.             
  1772.                 if ( fileChanged ) {
  1773.                     updateWindows = true;
  1774.                 }                    
  1775.                 currentDate = new Date();
  1776.                 var day = currentDate.getDate();
  1777.                 if ( reminderFox_lastDay  != day ) {
  1778.                     updateWindows = true;
  1779.                 }
  1780.                 reminderFox_logMessageLevel("Initialize: " + currentDate + " --Update?: " + updateWindows +" -- fileChanged: " + fileChanged + ",  changed: " + changed + ", dayChanged: " + (reminderFox_lastDay != day), REMINDER_FOX_LOG_LEVEL_INFO);
  1781.                 if ( updateWindows ) {
  1782.                     oldestWindow.reminderFox_updateRemindersInWindow();    
  1783.                     if ( clearReminders ) {
  1784.                         // clear reminders from memory
  1785.                         reminderFox_clearRemindersAndTodos();
  1786.                     }    
  1787.                     while (windowEnumerator.hasMoreElements()) {
  1788.                         var currentWindow = windowEnumerator.getNext();        
  1789.                         currentWindow.reminderFox_updateRemindersInWindow();        
  1790.                         if ( clearReminders ) {
  1791.                             // clear reminders from memory
  1792.                             currentWindow.reminderFox_clearRemindersAndTodos();
  1793.                         }                            
  1794.                     }
  1795.                 }
  1796.  
  1797.                 
  1798.                 if ( clearReminders ) {
  1799.                     // clear reminders from memory
  1800.                     reminderFox_clearRemindersAndTodos();
  1801.                 }            
  1802.                 reminderFox_lastDay  = day;    
  1803.                 reminderFox_logMessageLevel(currentDate + ": Setting Hourly timeout!", REMINDER_FOX_LOG_LEVEL_FINE);
  1804.                 reminderFox_storeTimeOfLastProcessed();
  1805.         
  1806.                 window.setTimeout(reminderFox_initializeReminderFoxHourly, reminderFox_HOUR_TIMEOUT);  // 10000 == 10 sec min
  1807.             }        
  1808.         }
  1809.     }
  1810. }
  1811.  
  1812.  
  1813. // this runs every hour and updates all of the windows with the latest reminders
  1814. function reminderFox_initializeReminderFoxHourly() {
  1815.     reminderFox_initializeReminderFox(true);
  1816. }
  1817.  
  1818. function reminderFox_updateRemindersInWindow() {
  1819.     reminderFox_logMessageLevel("Updating reminders in window: " + new Date(), REMINDER_FOX_LOG_LEVEL_INFO);     
  1820.     
  1821.     var text = document.getElementById('reminderFox-statusLabel');
  1822.     if (text != null) {
  1823.         var reminderString = "";
  1824.         
  1825.         var todaysAndUpcomingReminders = reminderFox_getTodaysAndUpcomingReminders();
  1826.         var remindersArray =todaysAndUpcomingReminders.today;
  1827.         var important = false;
  1828.         for ( var i = 0; i < remindersArray.length; i++ ) {
  1829.             reminderString = reminderString + remindersArray[i].summary;
  1830.             if ( i < remindersArray.length - 1 ) {  
  1831.                 reminderString = reminderString + ", ";
  1832.             }                
  1833.             if ( remindersArray[i].priority == REMINDER_PRIORITY_IMPORTANT ) {
  1834.                 important = true;
  1835.             }
  1836.         }
  1837.         if (reminderString != "") { 
  1838.             
  1839.           // get preference for how many chars to make this
  1840.           var statusTextMaxLen =    40;
  1841.           try {
  1842.                 statusTextMaxLen = reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." +  REMINDER_FOX_STATUS_TEXT_MAX_LENGTH);    
  1843.             }
  1844.             catch ( e) {
  1845.             }
  1846.             
  1847.             // don't want text on status bar too long; truncate it after it gets big
  1848.             if ( reminderString.length > statusTextMaxLen ) {
  1849.                 reminderString = reminderString.substring( 0, statusTextMaxLen ) + "...";
  1850.             }                    
  1851.  
  1852.             if ( important ) {
  1853.                 text.setAttribute("style", "color: red;");
  1854.             }
  1855.             else{
  1856.                 text.removeAttribute( "style" );
  1857.             }
  1858.  
  1859.             var showStatusText = true;
  1860.             try {
  1861.                 showStatusText = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_SHOW_STATUS_TEXT);
  1862.             } catch(e) {
  1863.             }
  1864.             if ( showStatusText ) {
  1865.                 text.setAttribute("class", "statusbarpanel-iconic-text");
  1866.                 text.setAttribute("label", reminderString);                    
  1867.             }
  1868.             else {
  1869.                 // user doesn't want the reminder text - just use icon
  1870.                 text.setAttribute("class", "statusbarpanel-iconic");
  1871.             }                    
  1872.         } else {
  1873.             text.setAttribute("class", "statusbarpanel-iconic");
  1874.         }
  1875.  
  1876.         reminderFox_createToolTip(remindersArray, todaysAndUpcomingReminders.upcoming);        
  1877.     }
  1878. }
  1879.  
  1880.  
  1881. function reminderFox_activateOptionsContext(event) {    
  1882.     // dynamically handle the Show Alerts menu item 
  1883.     var alertType;
  1884.     try {
  1885.         alertType = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_ENABLE_ALERT_PREF);
  1886.     } catch(e) {
  1887.         alertType = REMINDER_FOX_ENABLE_ALERT_PREF_ALL;
  1888.     }
  1889.             
  1890.     var suspendAlerts = document.getElementById("options-contextmenu-suspendAlerts");    
  1891.     if ( suspendAlerts != null ) { 
  1892.         // if the user has set it to no alerts, the option should be disabled
  1893.     //    if ( alertType == REMINDER_FOX_ENABLE_ALERT_PREF_NONE ) {
  1894.     //        suspendAlerts.setAttribute("disabled", "true");
  1895.     //        suspendAlerts.setAttribute("checked", "false");        
  1896.     //    }
  1897.         // if alerts are suspended, the option is unchecked
  1898.         if ( alertType.indexOf( REMINDER_FOX_SUSPEND_ALERT_PREF ) != -1 ) {
  1899.             suspendAlerts.setAttribute("disabled", "false");
  1900.             suspendAlerts.setAttribute("checked", "true");
  1901.             
  1902.         }
  1903.         // otherwise, in normal case the option is checked
  1904.         else {
  1905.             suspendAlerts.setAttribute("disabled", "false");
  1906.             suspendAlerts.setAttribute("checked", "false");
  1907.         }    
  1908.     }
  1909.     
  1910.     // check if any current quick alarms, and show/hide the menu item list as appropriate
  1911.     var currentAlarms = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_QUICK_ALARMS);
  1912.     
  1913.     var quickAlarmsList = document.getElementById("options-contextmenu-quickAlarms-list");        
  1914.     if (currentAlarms == null || currentAlarms.length == 0) {
  1915.         quickAlarmsList.setAttribute("hidden", "true");    
  1916.     }
  1917.     else {
  1918.         quickAlarmsList.removeAttribute( "hidden");    
  1919.         
  1920.         // show current lists...
  1921.         var moveToList = document.getElementById("options-contextmenu-quickAlarms-list-popup");    
  1922.         while (moveToList.hasChildNodes()) {
  1923.              moveToList.removeChild(moveToList.firstChild);
  1924.         }
  1925.         
  1926.         if ( currentAlarms != null ) {
  1927.             var beginIndex = currentAlarms.indexOf( "X-REMINDERFOX-VALARM:");
  1928.             while ( currentAlarms.length > 0 && beginIndex != -1 ) {
  1929.                 var snoozeIndex = currentAlarms.indexOf( "X-REMINDERFOX-SNOOZE:");
  1930.                 
  1931.                 var endTextIndex = snoozeIndex;
  1932.                 var notesText = null;
  1933.                 // check for notes
  1934.                 var notesIndex = currentAlarms.indexOf( "X-REMINDERFOX-NOTES:");
  1935.                 if ( notesIndex != -1 && notesIndex < snoozeIndex ) {
  1936.                     notesText = currentAlarms.substring( 
  1937.                         notesIndex + "X-REMINDERFOX-NOTES:".length, snoozeIndex    );
  1938.                     endTextIndex = notesIndex;
  1939.                 }
  1940.                 
  1941.                 beginIndex = currentAlarms.indexOf( "X-REMINDERFOX-VALARM:");
  1942.                 var alarmText = currentAlarms.substring( 
  1943.                     beginIndex + "X-REMINDERFOX-VALARM:".length, endTextIndex    );
  1944.             
  1945.                 if ( snoozeIndex != -1 ) {
  1946.                     var snoozeTimeIndex = currentAlarms.indexOf( ";PT", snoozeIndex );
  1947.                     if ( snoozeTimeIndex != -1 ) {
  1948.                         var alarmTime =     currentAlarms.substring( 
  1949.                         snoozeIndex + "X-REMINDERFOX-SNOOZE:".length, snoozeTimeIndex    );
  1950.                         var snoozeEndIndex = currentAlarms.indexOf( "M", snoozeTimeIndex );
  1951.                         var currentTime = new Date().getTime();
  1952.                         var actualAlarmTime = parseInt( alarmTime ) - currentTime;
  1953.                         currentAlarms = currentAlarms.substring(snoozeEndIndex + 1 );    
  1954.                         
  1955.                         var newDate = new Date( parseInt( alarmTime ) );
  1956.                         
  1957.                         var todaysDate = new Date();
  1958.                         var dateVar = null;
  1959.                         if ( newDate.getMonth() != todaysDate.getMonth() || newDate.getDate() != todaysDate.getDate() ) {
  1960.                             var dateVariableString;
  1961.                             try {
  1962.                                 dateVariableString = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LIST_DATE_LABEL);
  1963.                             } catch(e) {
  1964.                             }            
  1965.                             var dateString =reminderFox_getDateVariable( null, newDate, dateVariableString );    
  1966.                             dateVar = dateString + ", " +     reminderFox_mail_getTimeString( newDate );
  1967.                         }
  1968.                         else {
  1969.                              dateVar = reminderFox_mail_getTimeString( newDate );
  1970.                         }
  1971.                         
  1972.                         // add new menu item
  1973.                         var menuItem = document.createElement("menuitem");
  1974.                         menuItem.setAttribute( "id", alarmText );
  1975.                         menuItem.setAttribute( "label", alarmText + " (" + dateVar + ")" );
  1976.                         menuItem.setAttribute( "oncommand", "reminderFox_promptRemoveQuickAlarm(event.target)");
  1977.                         moveToList.appendChild(menuItem);
  1978.                     }
  1979.                 }
  1980.             }
  1981.         }    
  1982.     }
  1983. }
  1984.  
  1985. function reminderFox_promptRemoveQuickAlarm( target ) {
  1986.     var quickAlarmText =  target.getAttribute( "id" );
  1987.     
  1988.     var quickAlarmLabel =  target.getAttribute( "label" );
  1989.     
  1990.     
  1991.     // get Notes text if available
  1992.     var quickAlarms = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_QUICK_ALARMS);        
  1993.     if ( quickAlarms != null ) {
  1994.         var oldItem = quickAlarms.indexOf(quickAlarmText );
  1995.         if ( oldItem != -1 ) {
  1996.             // remove quick alarm
  1997.             var oldIndex = quickAlarms.lastIndexOf("X-REMINDERFOX-VALARM:", oldItem );        
  1998.             
  1999.             var snoozeIndex = quickAlarms.indexOf( "X-REMINDERFOX-SNOOZE:", oldIndex);
  2000.             var endTextIndex = snoozeIndex;
  2001.             var notesText = null;
  2002.             // check for notes
  2003.             var notesIndex = quickAlarms.indexOf( "X-REMINDERFOX-NOTES:");
  2004.             if ( notesIndex != -1 && notesIndex < snoozeIndex ) {
  2005.                 notesText = quickAlarms.substring( 
  2006.                     notesIndex + "X-REMINDERFOX-NOTES:".length, snoozeIndex    );
  2007.                     
  2008.                 if ( notesText.length > 0 ) {
  2009.                     // replace new line characters with actual newline
  2010.                     notesText = notesText.replace(new RegExp(/\\n/g),"\n");
  2011.                     quickAlarmLabel += "\n\n" + notesText;
  2012.                 }
  2013.             }
  2014.         }
  2015.     }
  2016.             
  2017.     
  2018.     
  2019.     
  2020.         var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
  2021.                         .getService(Components.interfaces.nsIPromptService);
  2022.         
  2023.         var flags=promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
  2024.                promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1;     
  2025.         var msg = quickAlarmLabel;
  2026.         var buttonPressed = promptService.confirmEx(window,  reminderFox_getBundle().getString( "rf.alarm.quickalarms.label" ) + " " + quickAlarmText,
  2027.               msg,  flags,  reminderFox_getBundle().getString( "rf.alarm.quickalarms.remove.label" ), 
  2028.             reminderFox_getBundle().getString( "rf.button.ok" ), null, null, {});          
  2029.           
  2030.         // cancel pressed
  2031.         if ( buttonPressed == 0 ) {    
  2032.             reminderFox_removeQuickAlarm( quickAlarmText );
  2033.         }      
  2034. }
  2035.  
  2036. function reminderFox_toggleShowAlert() {
  2037.     var alertType;
  2038.     try {
  2039.         alertType = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_ENABLE_ALERT_PREF);
  2040.     } catch(e) {
  2041.         alertType = REMINDER_FOX_ENABLE_ALERT_PREF_ALL;
  2042.     }
  2043.     
  2044.     // if it's marked as suspended, change to original value
  2045.     var suspendedIndex = alertType.indexOf( REMINDER_FOX_SUSPEND_ALERT_PREF ) ;        
  2046.     if ( suspendedIndex != -1 ) {
  2047.         alertType = alertType.substring( suspendedIndex + REMINDER_FOX_SUSPEND_ALERT_PREF.length );
  2048.     }
  2049.     // otherwise, suspend the alert
  2050.     else {
  2051.         alertType = REMINDER_FOX_SUSPEND_ALERT_PREF + alertType;
  2052.     }
  2053.     
  2054.     reminderFox_prefsBranch.setCharPref( REMINDER_FOX_ENABLE_ALERT_PREF, alertType);
  2055. }
  2056.  
  2057. function processKeyPressedOnReminderTree(event) {
  2058.     if (event.keyCode == 46)
  2059.         removeReminder();
  2060. }
  2061.  
  2062. function reminderFox_showAlertSlider() {
  2063.     var i;
  2064.     var remindersArray;
  2065.     var windowEnumerator =  reminderFox_getWindowEnumerator();
  2066.  
  2067.     if (windowEnumerator.hasMoreElements()) {
  2068.         var oldestWindow = windowEnumerator.getNext();
  2069.         // Only show the alert  for the oldest window (the first browser you opened).  
  2070.         // We don't want each new window to have its own timeout to respond to, because we only
  2071.         // need to show one alert for all browser windows
  2072.         if ( window == oldestWindow ) {
  2073.             // don't show if the user has showReminders deselected in tooltip...  in that case, there is no todayReminder label to copy for alert so it would fail
  2074.             var showReminders = true;            
  2075.             try {
  2076.                 showReminders = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_SHOW_REMINDERS_IN_TOOLTIP);
  2077.             } catch(e) {
  2078.             }        
  2079.         
  2080.             // Reshow alert after ALERT_TIMEOUT minutes.  -- (note: options dialog - needs to clear out lastAlert pref when changed)
  2081.             var alert_timeout = reminderFox_prefs.getIntPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_ALERT_TIMEOUT_PREF);
  2082.  
  2083.             if ( showReminders && alert_timeout > 0 ) {
  2084.                 // convert from minutes to milliseconds    
  2085.                 alert_timeout = alert_timeout * 60000; 
  2086.                 
  2087.                 // verify that the correct amount of time has elapsed since last alert slider.   Sometimes due to 
  2088.                 // what appears to be a FireFox bug, sometimes a large number of alert timeouts are called.  This
  2089.                 // ensures that only the correct one will display the alert slider after the proper amount of time
  2090.                 var lastTime =     reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." +  REMINDER_FOX_LAST_ALERT);
  2091.                   
  2092.                 var lastTimeElapsed = null;
  2093.                 if ( lastTime != null && lastTime != "" )  {
  2094.                     lastTimeElapsed = parseInt(lastTime) + alert_timeout;
  2095.                 }
  2096.                 var currentDate = new Date();
  2097.                 var currentTime =currentDate.getTime();
  2098.                 
  2099.                 reminderFox_logMessageLevel("Show AlertSlider? " + ((currentTime+100) >= lastTimeElapsed) + "...  Last time: " + lastTime + " - lastTimeElapsed: " 
  2100.                     + lastTimeElapsed + " - currentTime: " + currentTime
  2101.                     , REMINDER_FOX_LOG_LEVEL_INFO);
  2102.                     
  2103.                 if (lastTime == null ||  (currentTime+100) >= lastTimeElapsed ) {  // +100 as small buffer (sometimes times are slightly off)
  2104.  
  2105.                     // problem with MAC and alertslider
  2106.                     var appInfo = Components.classes["@mozilla.org/xre/app-info;1"]
  2107.                     .getService(Components.interfaces.nsIXULAppInfo);
  2108.                 
  2109.                     if ("1.9" > appInfo.platformVersion) {        // Gecko check 
  2110.                         var alertComponent = Components.classes["@mozilla.org/alerts-service;1"]
  2111.                         if ( alertComponent != null ) {
  2112.                            var alerts = alertComponent.getService(Components.interfaces.nsIAlertsService);
  2113.                         }   
  2114.                     }     else {
  2115.                         // due to some error with OS/2 use the previous code (for Gecko 1.8)
  2116.                         var alerts = Components.classes["@mozilla.org/alerts-service;1"].getService(Components.interfaces.nsIAlertsService);
  2117.                     
  2118.                     }                    
  2119. //                    var alerts = Components.classes["@mozilla.org/alerts-service;1"].getService(Components.interfaces.nsIAlertsService);
  2120.                     var alertType;
  2121.                     try {
  2122.                         alertType = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_ENABLE_ALERT_PREF);
  2123.                     } catch(e) {
  2124.                         alertType = REMINDER_FOX_ENABLE_ALERT_PREF_ALL;
  2125.                     }
  2126.                     
  2127.                     if ( alertType == REMINDER_FOX_ENABLE_ALERT_PREF_NONE ) {
  2128.                         return;
  2129.                     }
  2130.                     reminderFox_ensureRemindersSynchronized();
  2131.                     //var remoteChanged = reminderFox_ensureRemoteRemindersSynchronized(true);   // do we want  alarm sync too?
  2132.                     
  2133.                     // check for empty today/upcoming - if both empty then ignore - check if today equals none string; if so, then check if upcoming == none string 
  2134.                     var lblparent = document.getElementById("todaysRemindersBox").cloneNode(true);    
  2135.                     var lblparent2 = document.getElementById("upcomingRemindersBox").cloneNode(true);    
  2136.             
  2137.                     var children = null;
  2138.                     var children2 = null;
  2139.                     var todayPref = false;
  2140.                     var upcomingPref = false;
  2141.                     if ( alertType == REMINDER_FOX_ENABLE_ALERT_PREF_TODAY || alertType == REMINDER_FOX_ENABLE_ALERT_PREF_ALL ) {
  2142.                         children = lblparent.childNodes;
  2143.                         todayPref = true;
  2144.                     }                        
  2145.                     if ( alertType ==REMINDER_FOX_ENABLE_ALERT_PREF_UPCOMING || alertType == REMINDER_FOX_ENABLE_ALERT_PREF_ALL ) {
  2146.                         children2 = lblparent2.childNodes;
  2147.                         upcomingPref = true;
  2148.                     }    
  2149.                     var noToday = ( children == null || children.length == 0 || (  children.length == 1 && children[0].getAttribute( "value" ) == reminderFox_getBundle().getString( "rf.main.tooltip.reminders.none" )  ) );
  2150.                     var noUpcoming =  ( children2 == null || children2.length == 0 || (  children2.length == 1 && children2[0].getAttribute( "value" ) == reminderFox_getBundle().getString( "rf.main.tooltip.reminders.none" )  ) );
  2151.                     var ignoreAlert = noToday && noUpcoming;
  2152.                      if ( !ignoreAlert  ) {    
  2153.                          if ( !todayPref ) {
  2154.                              lblparent = null;
  2155.                          }
  2156.                          if ( !upcomingPref ) {
  2157.                              lblparent2 = null;
  2158.                          }
  2159.                            var newOptions = { todaysreminders: lblparent, upcomingreminders: lblparent2,  alertTypeToShow: alertType };                         
  2160.                          window.openDialog("chrome://reminderfox/content/alerts/reminderalert.xul",            "alert:alert", "chrome,dialog=yes,titlebar=no,popup=yes", newOptions );
  2161.                     }
  2162.                     
  2163.                     reminderFox_clearRemindersAndTodos();                
  2164.                     reminderFox_logMessageLevel("AlertSlider: " + currentDate, REMINDER_FOX_LOG_LEVEL_INFO);
  2165.                     reminderFox_storeTimeOfLastAlert();  
  2166.                     window.setTimeout(reminderFox_showAlertSlider, alert_timeout);   
  2167.                     
  2168.                 }
  2169.             }                    
  2170.         }
  2171.     }
  2172.     // add some extra checks in when showing alert slider; in case the setTimeout threads have been suspended, 
  2173.     // this will kick them off again if neccessary
  2174.     reminderFox_initializeReminderFoxHourly();
  2175. }
  2176.  
  2177.  
  2178. // Automatically save reminders to backup files on FireFox startup
  2179. // Files:
  2180. //    reminders.ics.bak1  <-- always write to this on startup
  2181. //    reminders.ics.bak2   <--- check this...  if exists and > 24 hours since bak1, copy bak2 to bak3 and copy bak1 to bak2
  2182. //    reminders.ics.bak3
  2183. function reminderFox_saveReminders() {
  2184.     try {
  2185.         // initialize backup files
  2186.         var file;
  2187.         var savefilePath;
  2188.         // check if user has specified a specific file path in their preferences
  2189.         try {    //gW_OSswitching    
  2190.             savefilePath = rmFx_getStoreFile4OS();
  2191.             // support for OSswitch
  2192.             // savefilePath = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_STORE_FILE);
  2193.         }
  2194.         catch ( e) {
  2195.         }
  2196.         try {
  2197.             netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
  2198.         } catch (e) {
  2199.             alert("Permission to save file was denied.");
  2200.         }    
  2201.         
  2202.         var baseFilePath;
  2203.         // if not, then use default location in profile
  2204.         if ( savefilePath == null || savefilePath == "" ) {
  2205.              file = Components.classes["@mozilla.org/file/directory_service;1"]
  2206.                      .getService(Components.interfaces.nsIProperties)
  2207.                   .get("ProfD", Components.interfaces.nsIFile);
  2208.     
  2209.               file.append( "reminderfox" );
  2210.               file.append( "reminderfox.ics"  );            
  2211.               baseFilePath = file.path;
  2212.         }
  2213.         else {
  2214.             baseFilePath = savefilePath;
  2215.         }    
  2216.     
  2217.         var filePath1 = baseFilePath + ".bak1";
  2218.         var filePath2 = baseFilePath + ".bak2";
  2219.         var filePath3 = baseFilePath + ".bak3";
  2220.         
  2221.         var origFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
  2222.         origFile.initWithPath( baseFilePath );
  2223.         
  2224.         var file2 = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
  2225.         file2.initWithPath( filePath2 );
  2226.         
  2227.         var file1 = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
  2228.         file1.initWithPath( filePath1 );
  2229.     
  2230.         // only write backup file if it differs from current file
  2231.         if ( !file1.exists() || file1.lastModifiedTime != origFile.lastModifiedTime)    {    
  2232.             // no file2 - create it
  2233.             if ( !file2.exists() ) {
  2234.                 // bak2 doesn't exist.  Let's just write out to it            
  2235.                 var leafName = file2.leafName;                            
  2236.                 var parentDir = file2.parent;
  2237.                 if ( file1.exists() ) {
  2238.                     // copy bak1 to bak2            
  2239.                     var parentDir = file2.parent;
  2240.                     var leafName = file2.leafName;
  2241.                     file1.copyTo( parentDir, leafName);            
  2242.                 }                
  2243.             }            
  2244.             else if ( file1.exists() && file1.lastModifiedTime != file2.lastModifiedTime)    {    // and only write out if backup2  file is actually different than backup1        
  2245.                 var timeDifference = file1.lastModifiedTime  - file2.lastModifiedTime;
  2246.  
  2247.                 // only copy bak1 to bak2 if it is over a day old
  2248.                 if ( timeDifference > REMINDER_FOX_ONE_DAY ) {    // greater than a day old; update 
  2249.                     // copy bak2 to bak3
  2250.                     var file3 = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
  2251.                     file3.initWithPath( filePath3 );
  2252.                     var leafName = file3.leafName;
  2253.                     if ( file3.exists() ) {
  2254.                         file3.remove( true );
  2255.                     }                
  2256.                     var parentDir = file2.parent;
  2257.                     file2.copyTo( parentDir,leafName);
  2258.                                 
  2259.                     // copy bak1 to bak2            
  2260.                     var parentDir = file2.parent;
  2261.                     var leafName = file2.leafName;
  2262.                     if ( file2.exists() ) { 
  2263.                         file2.remove( true );
  2264.                     }
  2265.                     file1.copyTo( parentDir, leafName);                                                
  2266.                 }
  2267.             }
  2268.  
  2269.             // write out current state to bak1
  2270.             if ( file1.exists() )     {
  2271.                 file1.remove(true);
  2272.             }    
  2273.             var leafName = file1.leafName;                            
  2274.             var parentDir = file1.parent;
  2275.             origFile.copyTo( parentDir,leafName);                                            
  2276.         }                
  2277.     }        
  2278.     catch ( e ) {
  2279.         reminderFox_logMessageLevel("Failed saving backup file: " + e.name + ": " + e.description + ": " + e.number + ": " + e.message, REMINDER_FOX_LOG_LEVEL_INFO);
  2280.     }
  2281. }
  2282.  
  2283. function reminderFox_processQuickAlarms(returnMissed) {
  2284.     var alarmInfos = new Array();
  2285.     var quickAlarms = reminderFox_getUnicodePref(REMINDER_FOX_PREF + "." + REMINDER_FOX_QUICK_ALARMS);        
  2286.     var delay = 1;
  2287.     if ( quickAlarms != null ) {
  2288.         var currentAlarms = quickAlarms;
  2289.         var beginIndex = currentAlarms.indexOf( "X-REMINDERFOX-VALARM:");
  2290.         while ( currentAlarms.length > 0 && beginIndex != -1 ) {
  2291.             var snoozeIndex = currentAlarms.indexOf( "X-REMINDERFOX-SNOOZE:");
  2292.             var endTextIndex = snoozeIndex;
  2293.             var notesText = null;
  2294.             // check for notes
  2295.             var notesIndex = currentAlarms.indexOf( "X-REMINDERFOX-NOTES:");
  2296.             if ( notesIndex != -1 && notesIndex < snoozeIndex ) {
  2297.                 notesText = currentAlarms.substring( 
  2298.                     notesIndex + "X-REMINDERFOX-NOTES:".length, snoozeIndex    );
  2299.                 endTextIndex = notesIndex;
  2300.             }
  2301.             
  2302.             
  2303.             beginIndex = currentAlarms.indexOf( "X-REMINDERFOX-VALARM:");
  2304.             var alarmText = currentAlarms.substring( 
  2305.                 beginIndex + "X-REMINDERFOX-VALARM:".length, endTextIndex    );
  2306.         
  2307.             if ( snoozeIndex != -1 ) {
  2308.                 var snoozeTimeIndex = currentAlarms.indexOf( ";PT", snoozeIndex );
  2309.                 if ( snoozeTimeIndex != -1 ) {
  2310.                     var alarmTime =     currentAlarms.substring( 
  2311.                         snoozeIndex + "X-REMINDERFOX-SNOOZE:".length, snoozeTimeIndex    );
  2312.                     var snoozeEndIndex = currentAlarms.indexOf( "M", snoozeTimeIndex );
  2313.                     if ( snoozeEndIndex != -1 ) {
  2314.                         var snoozeTime = currentAlarms.substring( 
  2315.                             (snoozeTimeIndex + ";PT".length), snoozeEndIndex  );                                
  2316.                             
  2317.                         var currentTime = new Date().getTime();
  2318.                         var actualAlarmTime = parseInt( alarmTime ) - currentTime;
  2319.                         
  2320.                         var processed = false;
  2321.                         if (returnMissed ) {
  2322.                             if ( actualAlarmTime < 0 ) {
  2323.  
  2324.                                 var newAlarm = { 
  2325.                                         quickAlarmText : alarmText,
  2326.                                         quickAlarmNotes : notesText,
  2327.                                         alarmTabPanel: null,
  2328.                                         alarmRecentReminder: null,
  2329.                                         alarmSnoozeTime: snoozeTime,
  2330.                                         alarmListName: null,
  2331.                                         alarmTimeString: null,
  2332.                                         alarmIsReminder: false,
  2333.                                         alarmIsTodo: false,
  2334.                                         alarmAlarmMissed: false,
  2335.                                         synccallback: reminderFox_networkSynchronizeCallback,
  2336.                                         clearLabelCallback: reminderFox_clearMailLabelCallback,
  2337.                                         alarmCurrentAlarmId: null,
  2338.                                         reminderTime: null,
  2339.                                         reminderTimeDifference : null 
  2340.                                     };
  2341.                                     
  2342.                                     alarmInfos[alarmInfos.length] = newAlarm;
  2343.                                     processed = true;
  2344.                             }
  2345.                         }
  2346.                         
  2347.                         if ( !processed ) {
  2348.                             if ( actualAlarmTime < 0 ) {
  2349.                                 actualAlarmTime = 0 + ( reminderFox_ALARM_DELAY * delay );
  2350.                                 delay++;
  2351.                             }                
  2352.                              
  2353.                             var windowEnumerator =  reminderFox_getWindowEnumerator();
  2354.                             if (windowEnumerator.hasMoreElements()) {
  2355.                                 var oldestWindow = windowEnumerator.getNext();
  2356.                                 oldestWindow.setTimeout('reminderFox_showQuickAlarm("'+alarmText+'","'+snoozeTime+'","'+notesText+'")', actualAlarmTime);
  2357.                                 reminderFox_logMessageLevel(new Date() + ": Setting quickalarm for " + alarmText + " -- snoozeTime: " + snoozeTime + " -- actualAlarmTime: " + actualAlarmTime , REMINDER_FOX_LOG_LEVEL_FINE);
  2358.                             }    
  2359.                         }    
  2360.                         currentAlarms = currentAlarms.substring(snoozeEndIndex + 1 );        
  2361.                     }
  2362.                 }                                    
  2363.             }
  2364.         }
  2365.     }        
  2366.     return alarmInfos;
  2367. }
  2368.  
  2369. function reminderFox_bindKeys() {
  2370.     var keyset = document.getElementById("reminderFox_keyset");
  2371.     var openRF = reminderFox_getPreferenceValue( REMINDER_FOX_KEY_SHORTCUT_OPEN );
  2372.     var addRF = reminderFox_getPreferenceValue( REMINDER_FOX_KEY_SHORTCUT_ADD);
  2373.     var valid = {
  2374.         accel: "accel",
  2375.         ctrl: "control",
  2376.         control: "control",
  2377.         shift: "shift",
  2378.         alt: "alt",
  2379.         meta: "meta"
  2380.     };
  2381.     
  2382.     if ( openRF != null && openRF.length > 0 ) {
  2383.         var value = openRF;
  2384.         var parts = value.split(/\s+/);
  2385.         var modifiers = [];
  2386.         var keychar = null;
  2387.         var keycode = null;
  2388.         for (var i = 0; i < parts.length; i++) {
  2389.             if (parts[i].toLowerCase() in valid)
  2390.                 modifiers.push(parts[i].toLowerCase());
  2391.             else if (parts[i].length == 1)
  2392.                 keychar = parts[i];
  2393.             else if ("DOM_VK_" + parts[i].toUpperCase() in Components.interfaces.nsIDOMKeyEvent)
  2394.                 keycode = "VK_" + parts[i].toUpperCase();
  2395.         }
  2396.         if (keychar || keycode) {
  2397.             var element = document.createElement("key");
  2398.             element.setAttribute("id", "key_open_RF");
  2399.             element.setAttribute("oncommand", "reminderFox_openAddRemindersDialog(true);");
  2400.             if (keychar)
  2401.                 element.setAttribute("key", keychar);
  2402.             else
  2403.                 element.setAttribute("keycode", keycode);
  2404.             element.setAttribute("modifiers", modifiers.join(","));
  2405.     
  2406.             keyset.appendChild(element);
  2407.         }
  2408.     }
  2409.     
  2410.     if ( addRF != null && addRF.length > 0 ) {
  2411.         var value = addRF;
  2412.         var parts = value.split(/\s+/);
  2413.         var modifiers = [];
  2414.         var keychar = null;
  2415.         var keycode = null;
  2416.         for (var i = 0; i < parts.length; i++) {
  2417.             if (parts[i].toLowerCase() in valid)
  2418.                 modifiers.push(parts[i].toLowerCase());
  2419.             else if (parts[i].length == 1)
  2420.                 keychar = parts[i];
  2421.             else if ("DOM_VK_" + parts[i].toUpperCase() in Components.interfaces.nsIDOMKeyEvent)
  2422.                 keycode = "VK_" + parts[i].toUpperCase();
  2423.         }
  2424.     
  2425.         if (keychar || keycode) {
  2426.             var element = document.createElement("key");
  2427.             element.setAttribute("id", "key_add_RF");
  2428.             element.setAttribute("oncommand", "reminderFox_quickAddReminder();");
  2429.             if (keychar)
  2430.                 element.setAttribute("key", keychar);
  2431.             else
  2432.                 element.setAttribute("keycode", keycode);
  2433.             element.setAttribute("modifiers", modifiers.join(","));
  2434.     
  2435.             keyset.appendChild(element);
  2436.         }
  2437.     }
  2438. }
  2439.  
  2440. function reminderFox_start() {
  2441.     // load the default preferences (only the very first time that reminderfox is started; not each new window)
  2442.     var windowEnumerator =  reminderFox_getWindowEnumerator();
  2443.     if (windowEnumerator.hasMoreElements()) {
  2444.         var oldestWindow = windowEnumerator.getNext();
  2445.         if ( window == oldestWindow ) {
  2446.             reminderFox_loadDefaultPreferences();  // only call the first time
  2447.             
  2448.             // do keybindings
  2449.             reminderFox_bindKeys();
  2450.             
  2451.             
  2452.         }
  2453.     }
  2454.  
  2455.     reminderFox_moveBox();
  2456.     
  2457.     rmFxMsg.whichMessenger();    // this sets the global parameters for
  2458.                                  // Messenger and TB/AB3
  2459.     
  2460.     var menu = document.getElementById("contentAreaContextMenu");
  2461.     if ( menu != null ) {         
  2462.           menu.addEventListener("popupshowing", reminderFox_ContextMenuPopup, false);
  2463.     }
  2464.  
  2465.     // 2009-02-25  TB3.x  add for popupshowing handling
  2466.      var msgContext = document.getElementById("mailContext");
  2467.      if (msgContext != null)
  2468.         msgContext.addEventListener("popupshowing", rmFxPopupCheck, false);
  2469.     
  2470.     //gW TB3 2008-05-05  add for popupshowing handling
  2471.      var msgContext = document.getElementById("messagePaneContext");
  2472.      if (msgContext != null)
  2473.         msgContext.addEventListener("popupshowing", rmFxPopupCheck, false);
  2474.     
  2475.      var thContext = document.getElementById("threadPaneContext");
  2476.      if (thContext != null)
  2477.         thContext.addEventListener("popupshowing", rmFxPopupCheck, false);
  2478.     
  2479.      var attContext = document.getElementById("attachmentListContext");
  2480.      if (attContext != null)
  2481.         attContext.addEventListener("popupshowing", rmFxPopupCheck, false);
  2482.  
  2483.     //gW_PB 2009-06-18        add Postbox handling
  2484.      var attContext = document.getElementById("dataPaneAttachmentContextMenu");
  2485.      if (attContext != null)
  2486.         attContext.addEventListener("popupshowing", rmFxPopupCheck, false);
  2487.  
  2488.  
  2489.     // if this is the very first window opened, then let's set the timeout on it.
  2490.     reminderFox_initializeReminderFox(false); 
  2491.  
  2492.     // Initialize reminder fox for the browser window
  2493.     var windowEnumerator =  reminderFox_getWindowEnumerator();
  2494.     if (windowEnumerator.hasMoreElements()) {
  2495.         var oldestWindow = windowEnumerator.getNext();
  2496.         if ( window != oldestWindow ) {
  2497.             //  it's just a new window, we'll load it (tooltips, status bar)
  2498.             reminderFox_updateRemindersInWindow();    
  2499.         }
  2500.         else {
  2501.             // if this is the very first window, save out the reminders to backup file(s)
  2502.             reminderFox_saveReminders();        
  2503.             
  2504.             // Show the alert slider when the reminders are first initialized.
  2505.             // Only show if this is the oldest window (the first browser you opened).  That is, 
  2506.             // if you open a new window, we do not need to show the alert again.  
  2507.             window.setTimeout(reminderFox_showAlertSlider, 5000);    // add a delay of 5 seconds to account for browser loading 
  2508.             
  2509.             //reminderFox_processQuickAlarms();                        
  2510.         }
  2511.     }
  2512.  
  2513.     // clear reminders from memory
  2514.     reminderFox_clearRemindersAndTodos();
  2515. }
  2516.  
  2517. function reminderFox_getTimeString( reminder, date ) {
  2518.     var timeString = null;
  2519.     var reminderDate = date;
  2520.     if ( reminder != null && date == null ) { 
  2521.         reminderDate = reminder.date;
  2522.     }
  2523.     if (reminder == null || !reminder.allDayEvent ) {
  2524.         try {
  2525.             var hours = reminderDate.getHours();
  2526.             var AMorPM;
  2527.                 
  2528.             var use24HourTime;
  2529.             try {
  2530.                 use24HourTime = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_USE_24_HOUR_TIME);
  2531.             } catch(e) {
  2532.             }                
  2533.             if (  use24HourTime ) {
  2534.                 AMorPM = "";
  2535.                 if ( hours < 10 ) {
  2536.                     hours = "0" + hours;
  2537.                 }
  2538.             }
  2539.             else {
  2540.                 AMorPM  =reminderFox_getBundle().getString("rf.add.time.PM");
  2541.                 if ( AMorPM != "" ) {
  2542.                     if ( hours < 12 ) {
  2543.                         AMorPM = reminderFox_getBundle().getString("rf.add.time.AM");
  2544.                     }
  2545.                     if ( hours == 0 ) {
  2546.                         hours = 12;
  2547.                     }
  2548.                     if ( hours >= 13 ) {
  2549.                         hours = hours -12;
  2550.                     }    
  2551.                 }    
  2552.             }
  2553.         
  2554.             var minutes = reminderDate.getMinutes();
  2555.             if ( minutes < 10 ) {
  2556.                 minutes = "0" + minutes;
  2557.             }
  2558.                             
  2559.             timeString = hours + reminderFox_getBundle().getString("rf.add.time.delimiter") + minutes;
  2560.             if ( AMorPM != "" ) {
  2561.                 timeString = timeString + " " + AMorPM;        
  2562.             }
  2563.         }
  2564.         catch ( e ) { 
  2565.         }
  2566.     }    
  2567.     return timeString;
  2568. }
  2569.  
  2570. function reminderFox_populateReminderLabel( reminder , template, date) {
  2571.     var reminderLabel = template;
  2572.  
  2573.     // Replace the [variables]    
  2574.     var startBracketIndex =reminderLabel.indexOf("[");
  2575.     while (startBracketIndex != -1) {
  2576.         var endBracketIndex = reminderLabel.indexOf("]", startBracketIndex);
  2577.         if (endBracketIndex != -1) {
  2578.             // Check for a fishy [
  2579.             if (endBracketIndex - startBracketIndex < 3) {
  2580.                 startBracketIndex = reminderLabel.indexOf("[", ++startBracketIndex);
  2581.             }
  2582.             else {
  2583.                 var variable = reminderLabel.substring(startBracketIndex + 1, endBracketIndex);            
  2584.                 var decodedVariable = reminderFox_decodeReminderLabelVariable(reminder, variable, date);
  2585.                 var decodedVariableLength = decodedVariable.length;
  2586.                 var startTrim = startBracketIndex;
  2587.                 var endTrim = endBracketIndex;
  2588.                 if ( variable == "time" && decodedVariableLength == 0 ) {
  2589.                     // trim the ( ) from around time if the time is empty (all-day event)
  2590.                     if ( reminderLabel.charAt( startBracketIndex - 1 ) == "(" &&
  2591.                         reminderLabel.charAt( endBracketIndex + 1 ) == ")"  ) {
  2592.                         startTrim = startTrim - 1;
  2593.                         endTrim = endTrim + 1;
  2594.                     }
  2595.                 }
  2596.                 reminderLabel = reminderLabel.substring(0, startTrim) + decodedVariable + reminderLabel.substring(endTrim + 1, reminderLabel.length);
  2597.                 startBracketIndex = reminderLabel.indexOf("[", startBracketIndex + decodedVariableLength);
  2598.             }
  2599.         }
  2600.         else {
  2601.             // no ending bracket....  break out.
  2602.             startBracketIndex = -1;
  2603.         }
  2604.     }
  2605.     return reminderLabel;
  2606. }
  2607.  
  2608. function reminderFox_getDaysUntilDate( targetDate ) {
  2609.     var currentDate = new Date();
  2610.     var date = new Date( targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate() );    
  2611.     date.setHours( 0, 0, 0 );
  2612.     currentDate.setHours( 0, 0, 0 );
  2613.     
  2614.     // The number of milliseconds in one day
  2615.     var ONE_DAY = 1000 * 60 * 60 * 24
  2616.  
  2617.     // Convert both dates to milliseconds
  2618.     var date1_ms = date.getTime()
  2619.     var date2_ms = currentDate.getTime()
  2620.  
  2621.     // Calculate the difference in milliseconds
  2622.     var difference_ms = Math.abs(date1_ms - date2_ms)
  2623.     
  2624.     // Convert back to days and return
  2625.     return Math.round(difference_ms/ONE_DAY)
  2626. }
  2627.  
  2628. function reminderFox_decodeReminderLabelVariable(reminder, variable, date) {
  2629.     var decodedVariable = "";
  2630.  
  2631.         //gW two-digit number !! 
  2632.         function dVal(val) { 
  2633.             if (val < 10) val = "0" + val;
  2634.             return val; 
  2635.         }
  2636.         
  2637.     switch (variable) {
  2638.         case "reminderDesc":
  2639.             decodedVariable = reminder.summary;
  2640.             break;
  2641.           case "longDay":
  2642.               if ( date != null ) {
  2643.                   decodedVariable = reminderFox_integerToLongDay(date.getDay());
  2644.               }
  2645.             break;
  2646.         case "shortDay":
  2647.             if ( date != null ) {
  2648.                 decodedVariable = reminderFox_integerToShortDay(date.getDay());
  2649.             }
  2650.             break;            
  2651.         case "longMonth":
  2652.             if ( date != null ) {
  2653.                 decodedVariable = reminderFox_integerToLongMonth(date.getMonth());
  2654.             }
  2655.             break;
  2656.         case "shortMonth":
  2657.             if ( date != null ) {
  2658.                 decodedVariable = reminderFox_integerToShortMonth(date.getMonth());
  2659.             }
  2660.             break;
  2661.         case "numMonth":
  2662.             if ( date != null ) {
  2663.                 decodedVariable = (date.getMonth() +1)  + "";
  2664.             }
  2665.             break;
  2666.         case "numMonth2":
  2667.             if ( date != null ) {
  2668.                 decodedVariable = dVal(date.getMonth() +1) + "";
  2669.             }
  2670.             break;
  2671.         case "date":
  2672.             if ( date != null ) {
  2673.                 decodedVariable = (date.getDate()) + "";
  2674.             }
  2675.             break;            
  2676.         case "date2":
  2677.             if ( date != null ) {
  2678.                 decodedVariable = dVal(date.getDate()) + "";
  2679.             }
  2680.             break;            
  2681.         case "longYear":
  2682.             if ( date != null ) {
  2683.                 decodedVariable = date.getFullYear() + "";
  2684.             }
  2685.             break;
  2686.         case "shortYear":
  2687.             if ( date != null ) {
  2688.                 var fullYear = date.getFullYear() + "";
  2689.                 decodedVariable = fullYear.substring(2);
  2690.             }
  2691.             break;
  2692.         case "time":
  2693.             if ( date != null ) {
  2694.                 if ( reminder != null ) { 
  2695.                     if (reminder.allDayEvent)
  2696.                         decodedVariable = "";
  2697.                     else
  2698.                         decodedVariable = reminderFox_getTimeString(reminder, date);
  2699.                 }
  2700.                 else {
  2701.                     decodedVariable = "";
  2702.                 }
  2703.             }
  2704.             break;            
  2705.         case "daysUntil":
  2706.             if ( date != null ) {
  2707.                 decodedVariable = reminderFox_getDaysUntilDate( date );
  2708.             }
  2709.             break;
  2710.         case "timeUntil":
  2711.             if ( date != null ) {
  2712.                 decodedVariable = reminderFox_getTimeUntilDate( date, reminder );
  2713.             }            
  2714.             break;
  2715.         case "category":
  2716.             if ( reminder.categories != null ) {           
  2717.                 decodedVariable = reminder.categories;
  2718.             }
  2719.             break;
  2720.            case "location":
  2721.                if ( reminder.location != null ) {
  2722.                 decodedVariable = reminder.location;
  2723.                }
  2724.             break;            
  2725.         default:
  2726.             decodedVariable = "[" + variable + "]";
  2727.             break;
  2728.     } 
  2729.     return decodedVariable;
  2730. }
  2731.  
  2732. function reminderFox_getTimeUntilDate( targetDate, reminder  ) {
  2733.     var currentDate = new Date();
  2734.     var date = new Date( targetDate.getFullYear(), targetDate.getMonth(), targetDate.getDate(), targetDate.getHours(), targetDate.getMinutes() );
  2735.  
  2736.     var ONE_DAY = 1000 * 60 * 60 * 24
  2737.  
  2738.     // Convert both dates to milliseconds
  2739.     var date1_ms = date.getTime()
  2740.     var date2_ms = currentDate.getTime()
  2741.  
  2742.     // Calculate the difference in milliseconds
  2743.     var difference_ms =date1_ms - date2_ms;
  2744.     if ( difference_ms < 0 ) {
  2745.         return "";  // this time has already passed
  2746.     }
  2747.     var days = (difference_ms/ONE_DAY)
  2748.     var returnval = "";
  2749.  
  2750.     if (days > 1)
  2751.        {
  2752.            var daysUntil = reminderFox_getDaysUntilDate( targetDate );
  2753.            if ( daysUntil == 1 ) {
  2754.                return daysUntil + " " + reminderFox_getBundle().getString("rf.reminderoptions.notify.day.label");  
  2755.            }
  2756.            else {
  2757.                return daysUntil + " " + reminderFox_getBundle().getString("rf.reminderoptions.notify.days.label");  
  2758.            }
  2759.     }
  2760.     else {
  2761.         // it's an all-day reminder.  Say '1 day' as smallest increment
  2762.         if ( reminder != null && reminder.allDayEvent ) {
  2763.             return "1" + " " + reminderFox_getBundle().getString("rf.reminderoptions.notify.day.label");  
  2764.         }
  2765.         
  2766.       //It's less than a day, try hours
  2767.       var ONE_HOUR = 1000 * 60 * 60
  2768.       var hours = (difference_ms/ONE_HOUR)
  2769.       if (hours > 1)
  2770.          {
  2771.          if (Math.round(hours) == 1)
  2772.             returnval = Math.round(hours) + " " + reminderFox_getBundle().getString("rf.reminderoptions.notify.hour.label");  
  2773.             else
  2774.             returnval = Math.round(hours) + " " + reminderFox_getBundle().getString("rf.reminderoptions.notify.hours.label");  
  2775.          }
  2776.       else {
  2777.           //It's less than an hour, showm minutes
  2778.             var ONE_MINUTE = 1000 * 60
  2779.            var minutes = (difference_ms/ONE_MINUTE);
  2780.            if (Math.round(minutes) == 1)
  2781.               returnval = Math.round(minutes) + " " + reminderFox_getBundle().getString("rf.reminderoptions.notify.minute.label");  
  2782.               else
  2783.               returnval = Math.round(minutes) + " " + reminderFox_getBundle().getString("rf.reminderoptions.notify.minutes.label");  
  2784.            }
  2785.     }
  2786.     return returnval
  2787. }
  2788.  
  2789.  
  2790. function reminderFox_integerToShortDay( dayOfWeek) {
  2791.     var shortDay = "";
  2792.     switch (dayOfWeek) {
  2793.         case 0:
  2794.             shortDay =  reminderFox_getBundle().getString("rf.options.day.0.name.Mmm");
  2795.             break;
  2796.           case 1:
  2797.               shortDay = reminderFox_getBundle().getString("rf.options.day.1.name.Mmm");
  2798.             break;
  2799.         case 2:
  2800.             shortDay =  reminderFox_getBundle().getString("rf.options.day.2.name.Mmm");
  2801.             break;            
  2802.         case 3:
  2803.             shortDay =  reminderFox_getBundle().getString("rf.options.day.3.name.Mmm");
  2804.             break;
  2805.         case 4:
  2806.             shortDay =  reminderFox_getBundle().getString("rf.options.day.4.name.Mmm");
  2807.             break;
  2808.         case 5:
  2809.             shortDay =  reminderFox_getBundle().getString("rf.options.day.5.name.Mmm");
  2810.             break;
  2811.         case 6:
  2812.             shortDay =  reminderFox_getBundle().getString("rf.options.day.6.name.Mmm");
  2813.             break;            
  2814.     } 
  2815.     return shortDay;
  2816. }
  2817.  
  2818. function reminderFox_integerToLongDay( dayOfWeek) {
  2819.     var longDay = "";
  2820.     switch (dayOfWeek) {
  2821.         case 0:
  2822.             longDay =  reminderFox_getBundle().getString("rf.options.day.0.name");
  2823.             break;
  2824.           case 1:
  2825.               longDay =  reminderFox_getBundle().getString("rf.options.day.1.name");
  2826.             break;
  2827.         case 2:
  2828.             longDay =  reminderFox_getBundle().getString("rf.options.day.2.name");
  2829.             break;            
  2830.         case 3:
  2831.             longDay =  reminderFox_getBundle().getString("rf.options.day.3.name");
  2832.             break;
  2833.         case 4:
  2834.             longDay =  reminderFox_getBundle().getString("rf.options.day.4.name");
  2835.             break;
  2836.         case 5:
  2837.             longDay =  reminderFox_getBundle().getString("rf.options.day.5.name");
  2838.             break;
  2839.         case 6:
  2840.             longDay =  reminderFox_getBundle().getString("rf.options.day.6.name");
  2841.             break;            
  2842.     } 
  2843.     return longDay;
  2844. }
  2845.  
  2846. function reminderFox_integerToLongMonth( monthOfYear ) {
  2847.     var longMonth = "";
  2848.     switch (monthOfYear) {
  2849.         case 0:
  2850.             longMonth =  reminderFox_getBundle().getString("rf.options.month.0.name");
  2851.             break;
  2852.           case 1:
  2853.               longMonth = reminderFox_getBundle().getString("rf.options.month.1.name");
  2854.             break;
  2855.         case 2:
  2856.             longMonth =  reminderFox_getBundle().getString("rf.options.month.2.name");
  2857.             break;            
  2858.         case 3:
  2859.             longMonth =  reminderFox_getBundle().getString("rf.options.month.3.name");
  2860.             break;
  2861.         case 4:
  2862.             longMonth =  reminderFox_getBundle().getString("rf.options.month.4.name");
  2863.             break;
  2864.         case 5:
  2865.             longMonth =  reminderFox_getBundle().getString("rf.options.month.5.name");
  2866.             break;
  2867.         case 6:
  2868.             longMonth =  reminderFox_getBundle().getString("rf.options.month.6.name");
  2869.             break;
  2870.           case 7:
  2871.               longMonth =  reminderFox_getBundle().getString("rf.options.month.7.name");
  2872.             break;
  2873.         case 8:
  2874.             longMonth =  reminderFox_getBundle().getString("rf.options.month.8.name");
  2875.             break;            
  2876.         case 9:
  2877.             longMonth =  reminderFox_getBundle().getString("rf.options.month.9.name");
  2878.             break;
  2879.         case 10:
  2880.             longMonth =  reminderFox_getBundle().getString("rf.options.month.10.name");
  2881.             break;
  2882.         case 11:
  2883.             longMonth = reminderFox_getBundle().getString("rf.options.month.11.name");
  2884.             break;          
  2885.     } 
  2886.     return longMonth;
  2887. }
  2888.  
  2889. function reminderFox_integerToShortMonth( monthOfYear ) {
  2890.     var shortMonth = "";
  2891.     switch (monthOfYear) {
  2892.         case 0:
  2893.             shortMonth =  reminderFox_getBundle().getString("rf.options.month.0.Mmm");
  2894.             break;
  2895.           case 1:
  2896.               shortMonth = reminderFox_getBundle().getString("rf.options.month.1.Mmm");
  2897.             break;
  2898.         case 2:
  2899.             shortMonth =  reminderFox_getBundle().getString("rf.options.month.2.Mmm");
  2900.             break;            
  2901.         case 3:
  2902.             shortMonth = reminderFox_getBundle().getString("rf.options.month.3.Mmm");
  2903.             break;
  2904.         case 4:
  2905.             shortMonth =  reminderFox_getBundle().getString("rf.options.month.4.Mmm");
  2906.             break;
  2907.         case 5:
  2908.             shortMonth =  reminderFox_getBundle().getString("rf.options.month.5.Mmm");
  2909.             break;
  2910.         case 6:
  2911.             shortMonth =  reminderFox_getBundle().getString("rf.options.month.6.Mmm");
  2912.             break;
  2913.         case 7:
  2914.             shortMonth =  reminderFox_getBundle().getString("rf.options.month.7.Mmm");
  2915.             break;
  2916.           case 8:
  2917.               shortMonth = reminderFox_getBundle().getString("rf.options.month.8.Mmm");
  2918.             break;
  2919.         case 9:
  2920.             shortMonth =  reminderFox_getBundle().getString("rf.options.month.9.Mmm");
  2921.             break;            
  2922.         case 10:
  2923.             shortMonth =  reminderFox_getBundle().getString("rf.options.month.10.Mmm");
  2924.             break;
  2925.         case 11:
  2926.             shortMonth =  reminderFox_getBundle().getString("rf.options.month.11.Mmm");
  2927.             break;         
  2928.     } 
  2929.     return shortMonth;
  2930. }
  2931.  
  2932. function reminderFox_addReminderForWebPage() {
  2933.     var textWindow = document.commandDispatcher.focusedWindow;
  2934.     var text = textWindow.getSelection();     
  2935.     var notes = null;
  2936.     if ( text != null ) {
  2937.         text = text.toString();        
  2938.         text =reminderFox_trim(text);
  2939.         if ( text.length > 0 ) {
  2940.             notes = text;
  2941.         }
  2942.     }
  2943.     
  2944.     var subject = content.document.title ;
  2945.     var url = content.location.href;
  2946.     
  2947.     var newDate = new Date();
  2948.     newDate.setDate( newDate.getDate() );  // default to using today's date for reminder
  2949.  
  2950.     var reminderId =reminderFox_generateUniqueReminderId( newDate );
  2951.     var    newReminderToBeAdded = new ReminderFoxEvent( reminderId, newDate, subject );
  2952.     //newReminderToBeAdded.messageID = remFoxMessageID;
  2953.     // newReminderToBeAdded.recurrence.type = REMINDER_RECURRENCE_ONETIME;
  2954.     newReminderToBeAdded.url = url;
  2955.     // add default message header info to the Notes section
  2956.     if ( notes != null ) {
  2957.         newReminderToBeAdded.notes = notes;
  2958.     }
  2959.         
  2960.     reminderFox_addReminderHeadlessly( newReminderToBeAdded );
  2961.     
  2962.  
  2963. }
  2964.  
  2965. function reminderFox_quickAddReminder() { 
  2966.     var newDate = new Date();    
  2967.     var reminderId =reminderFox_generateUniqueReminderId( newDate );
  2968.     var newReminderToBeAdded = new ReminderFoxEvent( reminderId, newDate, null );
  2969.         
  2970.     reminderFox_addReminderHeadlessly( newReminderToBeAdded );    
  2971. }
  2972.  
  2973. function reminderFox_ContextMenuPopup() {
  2974.     var addReminderMenuItem = document.getElementById("rf_addReminder");
  2975.     var subscribeReminderMenuItem = document.getElementById("rf_subscribeReminder");
  2976.     
  2977.     var contextMenusEnabled = true;            
  2978.     try {
  2979.         contextMenusEnabled = reminderFox_prefs.getBoolPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_ENABLE_CONTEXT_MENUS);
  2980.     } catch(e) {
  2981.     }            
  2982.     
  2983.     // user doesn't want context menus; hide them
  2984.     if (!contextMenusEnabled ) {
  2985.         addReminderMenuItem.hidden =true;
  2986.            subscribeReminderMenuItem.hidden = true;
  2987.            return;
  2988.     }
  2989.     
  2990.     addReminderMenuItem.hidden =false;
  2991.        subscribeReminderMenuItem.hidden = false;
  2992.      
  2993.     
  2994.     
  2995.     if (gContextMenu.onLink) {        
  2996.            addReminderMenuItem.hidden =true;
  2997.            subscribeReminderMenuItem.hidden = true;
  2998.            
  2999.            // show subscribe context item if a calendar-type link
  3000.         var currentLink =  gContextMenu.link.href;
  3001.         if ( currentLink != null ) {
  3002.             if ( currentLink.indexOf( "webcal") != -1 ||
  3003.                 currentLink.indexOf( "ical") != -1 ||
  3004.                 currentLink.indexOf( "ics") != -1 ) {                
  3005.                 subscribeReminderMenuItem.hidden = false;
  3006.             }                
  3007.         }
  3008.     }
  3009.     else {        
  3010.         addReminderMenuItem.hidden =false;
  3011.         subscribeReminderMenuItem.hidden = true;
  3012.     }
  3013. }
  3014.  
  3015.  
  3016. function reminderFox_subscribeWithReminderFox(subscriptionUrl) {
  3017. //gW D&D 2008-04
  3018.     if (subscriptionUrl == null) {       
  3019.     /*var*/ subscriptionUrl = gContextMenu.link.href;
  3020.     }
  3021.     // default name to the name of the ics file
  3022.     var name = null;
  3023.     var endIndex = subscriptionUrl.indexOf( ".ics" );
  3024.     if ( endIndex != -1 && endIndex == subscriptionUrl.length - ".ics".length ) {
  3025.         var slashIndex = subscriptionUrl.lastIndexOf( "/", endIndex );
  3026.         if ( slashIndex != -1 ) {
  3027.             name = subscriptionUrl.substring( slashIndex + 1, endIndex );
  3028.         }
  3029.     } 
  3030.     
  3031.     var callOptions = { added: false,  addEvent: 1,  currentItem: name, subscription: subscriptionUrl  };
  3032.     window.openDialog("chrome://reminderfox/content/options/addCustomList.xul",
  3033.         "reminderFox-editAdd-customList", "chrome,resizable,modal", callOptions );
  3034.     
  3035.     if ( callOptions.added == true ) {
  3036.         var added = false;
  3037.         // set new list name
  3038.         try { 
  3039.             var newListName = callOptions.currentItem;
  3040.             var todoLists = reminderFox_getPreferenceValue( REMINDER_FOX_TODO_LISTS );
  3041.              if ( todoLists != null && todoLists.length > 0) {          
  3042.                  todoLists = todoLists + "," + newListName;
  3043.              }
  3044.              else {
  3045.                  todoLists = newListName;
  3046.              }        
  3047.             reminderFox_setUnicodePref( REMINDER_FOX_TODO_LISTS, todoLists);
  3048.             
  3049.             // add subscription
  3050.             var subscriptions = reminderFox_getSubscriptions();                                
  3051.             if ( subscriptionUrl != null  ) {
  3052.                 subscriptions[callOptions.currentItem] = callOptions.subscription; 
  3053.                 reminderFox_writeSubscriptions( subscriptions );
  3054.                 added = true;
  3055.             }        
  3056.             reminderFox_prefs.savePrefFile(null); 
  3057.         } catch ( e ) {            
  3058.         }   
  3059.         
  3060.         if ( added ) {
  3061.             alert( "ReminderFox: " + reminderFox_getBundle().getString("rf.options.customlist.subscribe.confirm.title") + " " + subscriptionUrl);;
  3062.         }                                        
  3063.         else {
  3064.             alert( "ReminderFox: " + reminderFox_getBundle().getString("rf.options.customlist.subscribe.failed.title") + " " + subscriptionUrl);;
  3065.         }
  3066.     }
  3067. }
  3068.  
  3069. function reminderFox_onclickFunc(event, element) {
  3070.     oeDatePicker.launchAdd = true;
  3071.     var treeContextMenu = document.getElementById("oe-date-picker-popup");
  3072.     treeContextMenu.showPopup(element, event.screenX, event.screenY, "bottomleft", "topleft"); 
  3073. }
  3074.  
  3075. function reminderfox_showCalendar(event) {
  3076.     var show = false;
  3077.     if ( event == null ) {
  3078.         show = true;
  3079.     }
  3080.     else {
  3081.         var target =  event.target.getAttribute( "id" );
  3082.         if ( target == "oe-date-picker-popup" ) {
  3083.             // if the target is not the popup (it could be a tooltip) we ignore it
  3084.             show = true;
  3085.         }
  3086.  
  3087.     }
  3088.     
  3089.     if ( show ) {
  3090.         oeDatePicker.resizeCalendar();  
  3091.         var reminderDate =  new Date();
  3092.         oeDatePicker.onpopupshowing(reminderDate, true, false, true);    
  3093.     }    
  3094. }
  3095.  
  3096.       
  3097. // fmt Date/Time string with RmFx definition from 'Options' settings 
  3098.  
  3099. function    rmFx_getDatum() {
  3100.     var date = new Date();   
  3101.     
  3102.     var timeString = reminderFox_mail_getTimeString( date );
  3103.     var dateVariableString;
  3104.     try {
  3105.         dateVariableString = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + 
  3106.             "." + REMINDER_FOX_LIST_DATE_LABEL);
  3107.     } catch(e) { }
  3108.       
  3109.      return  reminderFox_getDateVariable( null, date, dateVariableString )
  3110.             + " " + timeString;
  3111. }